// Есть построитель, который все это инициирует и строит 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; } }
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); }
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; })); }
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); }
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"); } }
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)); }); }
// Использование 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()); }