Ejemplo n.º 1
0
        // Есть построитель, который все это инициирует и строит
        public void Build()
        {
            min = KeyFunction(sequence.Element(start).Get());
            max = KeyFunction(sequence.Element(start + number - 1).Get()); //TODO: Что-то надо делать при number == 0
            // Особый случай, когда n_scale < 1 или min == max. Тогда делается одна ячейка и особая функция
            if (n_scale < 1 || min == max)
            {
                n_scale    = 1;
                starts     = new long[1];
                starts[0]  = start;
                ToPosition = (int key) => 0;
            }
            else
            {
                starts     = new long[n_scale];
                ToPosition = (int key) => (int)(((long)key - (long)min) * (long)(n_scale - 1) / (long)((long)max - (long)min));
            }
            // Заполнение количеств элементов в диапазонах
            foreach (var ob in sequence.ElementValues(start, number))
            {
                int key      = KeyFunction(ob);
                int position = ToPosition(key);
                // Предполагаю, что начальная разметка массива - нули
                starts[position] += 1;
            }
            // Заполнение начал диапазонов
            long sum = start;

            for (int i = 0; i < n_scale; i++)
            {
                long num_els = starts[i];
                starts[i] = sum;
                sum      += num_els;
            }
        }
Ejemplo n.º 2
0
        public void Load()
        {
            // Маленький массив будет после загрузки пустым
            index_cell_small.Clear();
            index_cell_small.Fill(new object[0]); index_cell_small.Flush();
            index_cell.Clear();
            index_cell.Fill(new object[0]);
            foreach (var rec in table.Elements().Where(ent => (bool)ent.Field(0).Get() == false)) // загрузка всех элементов за исключением уничтоженных
            {
                long offset = rec.offset;
                index_cell.Root.AppendElement(offset);
            }
            index_cell.Flush();
            if (index_cell.Root.Count() == 0)
            {
                return;                               // потому что следующая операция не пройдет
            }
            // Сортировать index_cell специальным образом: значение (long) используется как offset ячейки и там прочитывается нулевое поле
            var ptr = table.Element(0);

            //index_cell.Root.SortByKey<Tkey>((object v) =>
            index_cell.Root.SortByKey <Tkey>((object v) =>
            {
                ptr.offset = (long)v;
                return(keyProducer(ptr));
            }, comparer);
        }
Ejemplo n.º 3
0
        public IEnumerable <PaEntry> Search(string sample)
        {
            PaEntry entry_table = table.Element(0);

            return(key_index.SearchAll(sample).Select(ent =>
            {
                object[] v3 = (object[])ent.Get();
                entry_table.offset = (long)v3[1];
                return entry_table;
            }));
        }
Ejemplo n.º 4
0
        public void Load(Func <PaEntry, object[][]> genTriples)
        {
            intern_cell.Clear();
            intern_cell.Fill(new object[0]);
            foreach (PaEntry rec in table.Elements())
            {
                object[][] triples = genTriples(rec);
                foreach (object[] v3 in triples)
                {
                    intern_cell.Root.AppendElement(new object[] { false, v3[0], v3[1], v3[2], v3[3] });
                }
            }
            intern_cell.Flush();
            key_index.Load();
            key_index.AdditionalIndex(3); // дополнительный индекс - предикат

            //Проставим начала групп обратных ссылок и длину групп
            long    inv_beg = Int64.MinValue, inv_count = Int64.MinValue; // offset начала серии в intern_cell и длина серии
            PaEntry tab_el_ent = table.Element(0);
            long    key_offset = Int64.MaxValue;                          // будем фиксировать серию по совпадению оффсета с полем цели

            foreach (PaEntry ent in key_index.GetAll())
            {
                object[] v5      = (object[])ent.Get();
                long     tab_pnt = (long)v5[4]; // указатель на таблицу
                if (tab_pnt != key_offset)
                {                               // заканчивается серия, начинается новая серия
                    if (key_offset != Int64.MaxValue)
                    {                           // надо закончить предыдущую серию
                        tab_el_ent.offset = key_offset;
                        tab_el_ent.Field(5).Set(inv_beg);
                        tab_el_ent.Field(6).Set(inv_count);
                    }
                    // установим новую серию
                    key_offset = tab_pnt;
                    inv_beg    = ent.offset;
                    inv_count  = 0;
                }
                inv_count++;
            }
            // закончим последнюю серию
            tab_el_ent.offset = key_offset;
            tab_el_ent.Field(5).Set(inv_beg);
            tab_el_ent.Field(6).Set(inv_count);
        }
Ejemplo n.º 5
0
        public void Load()
        {
            index_cell.Clear();
            index_cell.Fill(new object[0]);
            foreach (var rec in table.Elements().Where(ent => (bool)ent.Field(0).Get() == false))
            {
                long offset = rec.offset;
                index_cell.Root.AppendElement(offset);
            }
            index_cell.Flush();
            if (index_cell.Root.Count() == 0)
            {
                return;                               // потому что следующая операция не пройдет
            }
            // Попробую сортировать index_cell специальным образом: значение (long) используется как offset ячейки и там прочитывается нулевое поле
            var ptr = table.Element(0);

            if (columnType.Vid == PTypeEnumeration.integer)
            {
                index_cell.Root.SortByKey <int>((object v) =>
                {
                    ptr.offset = (long)v;
                    return((int)ptr.Field(i_field).Get());
                });
            }
            else if (columnType.Vid == PTypeEnumeration.longinteger)
            {
                index_cell.Root.SortByKey <long>((object v) =>
                {
                    ptr.offset = (long)v;
                    return((long)ptr.Field(i_field).Get());
                });
            }
            else if (columnType.Vid == PTypeEnumeration.sstring)
            {
                index_cell.Root.SortByKey <string>((object v) =>
                {
                    ptr.offset = (long)v;
                    return((string)ptr.Field(i_field).Get());
                });
            }
            else if (columnType.Vid == PTypeEnumeration.real)
            {
                index_cell.Root.SortByKey <double>((object v) =>
                {
                    ptr.offset = (long)v;
                    return((double)ptr.Field(i_field).Get());
                });
            }
            else
            {
                throw new Exception("Wrong type of column for indexing");
            }
        }
Ejemplo n.º 6
0
        public void Load <Tkey>(Func <PaEntry, Tkey> keyProducer)
        {
            index_cell.Clear();
            index_cell.Fill(new object[0]);
            foreach (var rec in table.Elements().Where(ent => (bool)ent.Field(0).Get() == false))
            {
                long offset = rec.offset;
                index_cell.Root.AppendElement(offset);
            }
            index_cell.Flush();
            if (index_cell.Root.Count() == 0)
            {
                return;                               // потому что следующая операция не пройдет
            }
            // Попробую сортировать index_cell специальным образом: значение (long) используется как offset ячейки и там прочитывается нулевое поле
            var ptr = table.Element(0);

            index_cell.Root.SortByKey <Tkey>((object v) =>
            {
                ptr.offset = (long)v;
                return(keyProducer(ptr));
            });
        }
Ejemplo n.º 7
0
        // Использование GetFirst:
        //var qu = iset_index.GetFirst(ent =>
        //{
        //    int v = (int)ent.Get();
        //    return v.CompareTo(sample);
        //});

        private PaEntry GetFirstFromByKey(PaCell iCell, TKey key)
        {
            var entry  = table.Element(0);
            var entry2 = table.Element(0); // сделан, потому что может entry во внешнем и внутренниц циклах проинтерферируют?

            return(iCell.Root.BinarySearchAll(ent =>
            {
                var off1 = (long)ent.Get();
                entry.offset = off1;
                return ((IComparable)keyProducer(entry)).CompareTo(key);
            }) // здесь мы имеем множество найденных входов в ячейку i_cell
                   .Select(ent =>
            {
                entry2.offset = (long)ent.Get();              // вход в запись таблицы
                return entry2;
            })                                                // множество входов, удовлетворяющих условиям
                   .Where(tEnt => !(bool)tEnt.Field(0).Get()) // остаются только неуничтоженные
                   .DefaultIfEmpty(PaEntry.Empty)             // а вдруг не останется ни одного, тогда - пустышка
                   .First());
        }