public IEnumerable <object> GetAllByKey(int key) { long start = 0; long number = keyoffsets.Count(); if (scale != null && scale.GetDia != null) { Diapason dia = scale.GetDia(key); start = dia.start; number = dia.numb; } return(GetAllByKey(start, number, key) .Select(off => bearing.GetElement(off))); }
public IEnumerable <object> GetAllBySample(object sample) { long start = 0; long number = keyoffsets.Count(); int key = keyFun(sample); if (scale != null && scale.GetDia != null) { Diapason dia = scale.GetDia(key); start = dia.start; number = dia.numb; } return(BinarySearchAll(start, number, key, sample) .Select(off => bearing.GetElement(off))); }
public Scale(Stream stream) { keylengthminmaxstarts = new UniversalSequenceBase(new PType(PTypeEnumeration.integer), stream); int nvalues = (int)keylengthminmaxstarts.Count(); if (nvalues > 0) { keysLength = (int)keylengthminmaxstarts.GetByIndex(0); min = (int)keylengthminmaxstarts.GetByIndex(1); max = (int)keylengthminmaxstarts.GetByIndex(2); n_scale = nvalues - 3; starts = new int[n_scale]; for (int i = 3; i < nvalues; i++) { starts[i - 3] = (int)keylengthminmaxstarts.GetByIndex(i); } SetToPosition(); SetGetDia(); } }
public void Build() { // формируем массив пар int ne = (int)bearing.Count(); //KeyOffPair[] keyoff_arr = new KeyOffPair[ne]; int[] keys = new int[ne]; long[] offsets = new long[ne]; int ind = 0; bearing.Scan((off, obj) => { offsets[ind] = off; keys[ind] = keyFun(obj); ind++; return(true); }); // Сортируем по ключу Array.Sort(keys, offsets); // Эта часть делается если компаратор объектов comp задан if (comp != null) { // массив объектов List <object> objs = new List <object>(); // проходим по массиву ключей, в группах одинаковых ключей выделяем массив объектов int key, start = -1; // начало интервала и количество с одинаковым ключом key = Int32.MinValue; Action fixgroup = () => { int number = objs.Count; if (number > 1) { long[] offs_small = new long[number]; for (int j = 0; j < number; j++) { offs_small[j] = offsets[start + j]; } // Сортировка отрезка Array.Sort(objs.ToArray(), offs_small, comp); // вернуть отсортированные офсеты на место for (int j = 0; j < number; j++) { offsets[start + j] = offs_small[j]; } } }; for (int i = 0; i < ne; i++) { object ob = bearing.GetElement(offsets[i]); int k = keyFun(ob); // смена ключа if (i == 0 || k != key) { // фиксируем предыдущий отрезок (key, start, number) //FixGroup(offsets, objs, start); fixgroup(); // Начать новый отрезок key = k; start = i; objs.Clear(); } // основное действие objs.Add(ob); } if (objs.Count > 1) { fixgroup(); } } // Записываем keyoffsets.Clear(); // очищаем for (int i = 0; i < keys.Length; i++) { keyoffsets.AppendElement(new object[] { keys[i], offsets[i] }); } keyoffsets.Flush(); if (scale != null) { scale.Load(keys); } }
public long Count() { return(keyoffsets.Count()); }
private object[] rare_elements = null; // -- public void Build() { // Формируем последовательность offset_sequ offset_sequ.Clear(); bearing.Scan((off, obj) => { bool isapp = applicable(obj); if (applicable(obj)) { offset_sequ.AppendElement(off); } return(true); }); offset_sequ.Flush(); // Возможно, нам понадобятся два дополнительных стрима FileStream tmp_stream1 = null; FileStream tmp_stream2 = null; // Определяем рекурсивный метод построения Bld(long start_ind, long number) который в итоге переупорядочивает // отрезок последовательности offset_sequ так, что ссылаемые элементы становятся отсортированными. void Bld(long start_ind, long number) { if (number <= volume_of_offset_array) { long[] offsets = new long[number]; object[] elements = new object[number]; // берем в массивы for (long i = 0; i < number; i++) { long off = (long)offset_sequ.GetByIndex(start_ind + i); offsets[i] = off; elements[i] = bearing.GetItem(off); } // Сортируем Array.Sort(elements, offsets, comp_default); // кладем из массивов в последовательность for (long i = 0; i < number; i++) { if (i == 0) { offset_sequ.SetElement(offsets[i], offset_sequ.ElementOffset(start_ind)); } else { offset_sequ.SetElement(offsets[i]); } } } else { // надо разбить отрезок на два, в каждом сделать сортировку, а результаты слить. long firsthalf_start = start_ind; long firsthalf_number = number / 2; long secondhalf_start = start_ind + firsthalf_number; long secondhalf_number = number - firsthalf_number; Bld(firsthalf_start, firsthalf_number); Bld(secondhalf_start, secondhalf_number); if (tmp_stream1 == null) { tmp_stream1 = File.Open(tmpdir + "tmp1.$$$", FileMode.OpenOrCreate, FileAccess.ReadWrite); } if (tmp_stream2 == null) { tmp_stream2 = File.Open(tmpdir + "tmp2.$$$", FileMode.OpenOrCreate, FileAccess.ReadWrite); } tmp_stream1.Position = 0L; tmp_stream2.Position = 0L; byte[] buffer = new byte[buffersize]; Stream source1 = offset_sequ.Media; source1.Position = 8 + firsthalf_start * 8; long nbytes1 = firsthalf_number * 8; while (nbytes1 > 0) { int nb = source1.Read(buffer, 0, nbytes1 >= buffer.Length ? buffer.Length : (int)nbytes1); tmp_stream1.Write(buffer, 0, nb); nbytes1 -= nb; } Stream source2 = offset_sequ.Media; source2.Position = 8 + secondhalf_start * 8; long nbytes2 = secondhalf_number * 8; while (nbytes2 > 0) { int nb = source2.Read(buffer, 0, nbytes2 >= buffer.Length ? buffer.Length : (int)nbytes2); tmp_stream2.Write(buffer, 0, nb); nbytes2 -= nb; } tmp_stream1.Position = 0L; BinaryReader br1 = new BinaryReader(tmp_stream1); long off1 = br1.ReadInt64(); object obj1 = bearing.GetItem(off1); long nom1 = 0; // номер обрабатываемого элемента tmp_stream2.Position = 0L; BinaryReader br2 = new BinaryReader(tmp_stream2); long off2 = br2.ReadInt64(); object obj2 = bearing.GetItem(off2); long nom2 = 0; // номер обрабатываемого элемента long out_ind = start_ind; while (nom1 < firsthalf_number && nom2 < secondhalf_number) { if (comp_default.Compare(obj1, obj2) <= 0) { offset_sequ.SetElement(off1, offset_sequ.ElementOffset(out_ind)); nom1++; if (nom1 < firsthalf_number) { off1 = br1.ReadInt64(); obj1 = bearing.GetItem(off1); } } else { offset_sequ.SetElement(off2, offset_sequ.ElementOffset(out_ind)); nom2++; if (nom2 < secondhalf_number) { off2 = br2.ReadInt64(); obj2 = bearing.GetItem(off2); } } out_ind++; } // Перепись остатков if (nom1 < firsthalf_number) { for (long ii = nom1; ii < firsthalf_number; ii++) { if (ii != nom1) { off1 = br1.ReadInt64(); } offset_sequ.SetElement(off1, offset_sequ.ElementOffset(out_ind)); out_ind++; } } else if (nom2 < secondhalf_number) { for (long ii = nom2; ii < secondhalf_number; ii++) { if (ii != nom2) { off2 = br2.ReadInt64(); } offset_sequ.SetElement(off2, offset_sequ.ElementOffset(out_ind)); out_ind++; } } } }; // Исполним Bld(0L, offset_sequ.Count()); if (tmp_stream1 != null) { tmp_stream1.Close(); File.Delete(tmpdir + "tmp1.$$$"); } if (tmp_stream2 != null) { tmp_stream2.Close(); File.Delete(tmpdir + "tmp2.$$$"); } Refresh(); }
public long Count() { return(sequence.Count()); }