private void Load(IEnumerable <object> triples) { table.Clear(); foreach (object tri in triples) { long off = table.AppendElement(tri); } table.Flush(); }
// ==================== Динамика =================== private int SetStr(string s) { int code = (int)table.Count(); long off = table.AppendElement(new object[] { code, s }); str_offsets.AppendElement(off); dyna_index.Add(s, code); // нужен итоговый Flush по двум последовательностям return(code); }
public void Load(IEnumerable <object> triples) { table.Clear(); foreach (object tri in triples) { long off = table.AppendElement(tri); index_spo.AppendElement(off); } table.Flush(); index_spo.Flush(); }
public void Load(IEnumerable <object> triples) { table.Clear(); foreach (object tri in triples) { long off = table.AppendElement(tri); int key = keyFunc(tri); index_spo.AppendElement(new object[] { key, off }); } table.Flush(); index_spo.Flush(); }
public void SaveFlowToSequence(IEnumerable <object> flow, string path) { var file = File.Open(path, FileMode.OpenOrCreate, FileAccess.ReadWrite); UniversalSequenceBase sequ = new UniversalSequenceBase(tp_Record, file); sequ.Clear(); foreach (var ob in flow) { sequ.AppendElement(ob); } sequ.Flush(); file.Close(); }
// ==================== Динамика =================== /// <summary> /// Добавление НОВОГО имени, получение кода /// </summary> /// <param name="s"></param> /// <returns></returns> private int SetStr(string s) { // Новый код определяется, записывается в основную таблицу, записывается в таблицу офсетов, записывается в динамический индекс int code = (int)cod_str.Count(); long off = cod_str.AppendElement(new object[] { code, s }); offsets.AppendElement(off); if (dyna_index.Count > 100_000_000) { System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); Flush(); Build(); sw.Stop(); Console.WriteLine($"Build() {sw.ElapsedMilliseconds}"); } else { dyna_index.Add(s, code); } // нужен итоговый Flush по двум последовательностям return(code); }
public static void Main303() { Console.WriteLine("Start Main303"); // Создадим типы записи и последовательности записей PType tp_rec = new PTypeRecord( new NamedType("id", new PType(PTypeEnumeration.integer)), new NamedType("name", new PType(PTypeEnumeration.sstring)), new NamedType("age", new PType(PTypeEnumeration.integer))); PType tp_seq = new PTypeSequence(tp_rec); // ======== Универсальная последовательность ========== Stream stream = File.Open(datadirectory_path + "data303.bin", FileMode.OpenOrCreate); UniversalSequenceBase sequence = new UniversalSequenceBase(tp_rec, stream); Random rnd = new Random(); int nelements = 10_000_000; // При заполнении массива, сохраним офсеты элементов в массиве long[] offsets = new long[nelements]; int[] keys = new int[nelements]; bool toload = true; if (toload) { sw.Restart(); sequence.Clear(); for (int i = 0; i < nelements; i++) { int key = nelements - i - 1; offsets[i] = sequence.AppendElement(new object[] { key, "Иванов" + key, rnd.Next(1, 110) }); keys[i] = key; } // отсортируем пару массивов keys, offsets по ключам Array.Sort(keys, offsets); sw.Stop(); Console.WriteLine($"Load of {nelements} elements. duration={sw.ElapsedMilliseconds}"); } else { int ind = 0; sequence.Scan((off, obj) => { offsets[ind] = off; keys[ind] = (int)((object[])obj)[0]; ind++; return(true); }); // отсортируем пару массивов keys, offsets по ключам Array.Sort(keys, offsets); } // Будем делать выборку элементов по ключу sw.Restart(); int ntests = 1000; for (int j = 0; j < ntests; j++) { int key = rnd.Next(nelements); int nom = Array.BinarySearch(keys, key); long off = offsets[nom]; object[] fields = (object[])sequence.GetElement(off); if (key != (int)fields[0]) { throw new Exception("1233eddf"); } //Console.WriteLine($"key={key} {fields[0]} {fields[1]} {fields[2]}"); } sw.Stop(); Console.WriteLine($"duration of {ntests} tests is {sw.ElapsedMilliseconds} ms."); }
public static void Main402() { Console.WriteLine("Start Main402"); // Создадим типы записи и последовательности записей PType tp_rec = new PTypeRecord( new NamedType("id", new PType(PTypeEnumeration.integer)), new NamedType("name", new PType(PTypeEnumeration.sstring)), new NamedType("age", new PType(PTypeEnumeration.integer))); PType tp_seq = new PTypeSequence(tp_rec); // ======== Универсальная последовательность ========== Stream stream = File.Open(datadirectory_path + "first_data.bin", FileMode.OpenOrCreate); UniversalSequenceBase sequence = new UniversalSequenceBase(tp_rec, stream); Random rnd = new Random(); int nelements = 100_000; // Последовательность создается пустой или она может быть очищена sequence.Clear(); // В последовательность можно добавлять элементы в объектном представлении for (int i = 0; i < nelements; i++) { sequence.AppendElement(new object[] { i, "Иванов" + i, rnd.Next(1, 110) }); } // Серию записей обязательно надо завершать сбросом буферов sequence.Flush(); // Изучим полученную последовательность Console.WriteLine($"Count={sequence.Count()}"); foreach (object[] r in sequence.ElementValues().Skip(50_000).Take(20)) { Console.WriteLine($"{r[0]} {r[1]} {r[2]} "); } // При заполнении массива, сохраним офсеты элементов в массиве long[] offsets = new long[nelements]; int[] keys = new int[nelements]; sequence.Clear(); for (int i = 0; i < nelements; i++) { int key = nelements - i - 1; offsets[i] = sequence.AppendElement(new object[] { key, "Иванов" + key, rnd.Next(1, 110) }); keys[i] = key; } // отсортируем пару массивов keys, offsets по ключам Array.Sort(keys, offsets); // Будем делать выборку элементов по ключу sw.Restart(); int ntests = 10_000; for (int j = 0; j < ntests; j++) { int key = rnd.Next(nelements); int ind = Array.BinarySearch(keys, key); long off = offsets[ind]; object[] fields = (object[])sequence.GetElement(off); //Console.WriteLine($"key={key} {fields[0]} {fields[1]} {fields[2]}"); } sw.Stop(); Console.WriteLine($"duration of {ntests} tests is {sw.ElapsedMilliseconds} ms."); }
public static void Main15() { string path = "../../../"; Random rnd = new Random(); int cnt = 0; System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); Console.WriteLine("Start Main15"); Func <Stream> streamGen = () => new FileStream(path + "Databases/g" + (cnt++) + ".bin", FileMode.OpenOrCreate, FileAccess.ReadWrite); PType tp_person = new PTypeRecord( new NamedType("id", new PType(PTypeEnumeration.integer)), new NamedType("name", new PType(PTypeEnumeration.sstring)), new NamedType("years", new PType(PTypeEnumeration.real))); Comparer <object> comp_string = Comparer <object> .Create(new Comparison <object>((object a, object b) => { var aa = (string)((object[])a)[1]; var bb = (string)((object[])b)[1]; return(aa.CompareTo(bb)); })); UniversalSequenceBase table = new UniversalSequenceBase(tp_person, streamGen()); IndexKey32CompImm id_index = new IndexKey32CompImm(streamGen, table, ob => (int)((object[])ob)[0], null); //IndexKey32CompImm namehash_index = new IndexKey32CompImm(streamGen, table, // ob => Hashfunctions.HashRot13((string)((object[])ob)[1]), null); //IndexKey32CompImm namehash_index_full = new IndexKey32CompImm(streamGen, table, // ob => Hashfunctions.HashRot13((string)((object[])ob)[1]), comp_string); IndexViewImmutable nameview_index = new IndexViewImmutable(streamGen, table, comp_string, path + "Databases/", 50_000_000); int nelements = 1_000_000; Console.WriteLine($" nelements={nelements}"); // Загрузка bool toload = true; if (toload) { sw.Restart(); var dataflow = Enumerable.Range(0, nelements) .Select(nom => new object[] { nelements - nom - 1, "" + (nelements - nom - 1), rnd.NextDouble() * 100D }); table.Clear(); foreach (object[] element in dataflow) { table.AppendElement(element); } table.Flush(); id_index.Build(); //namehash_index.Build(); //namehash_index_full.Build(); nameview_index.Build(); sw.Stop(); Console.WriteLine($"Indexes ok. duration={sw.ElapsedMilliseconds}"); } else { sw.Restart(); table.Refresh(); id_index.Refresh(); //namehash_index.Refresh(); //namehash_index_full.Refresh(); nameview_index.Refresh(); sw.Stop(); Console.WriteLine($"refresh {nelements} ok. duration={sw.ElapsedMilliseconds}"); } int id = nelements * 2 / 3; int nprobe = 1000; int total = 0; var query1 = id_index.GetAllBySample(new object[] { id, null, -1.0D }); foreach (var obj in query1) { Console.WriteLine(tp_person.Interpret(obj)); } sw.Restart(); for (int i = 0; i < nprobe; i++) { id = rnd.Next(nelements); total += id_index.GetAllBySample(new object[] { id, null, -1.0D }).Count(); } sw.Stop(); Console.WriteLine($"GetById {nprobe} probes. duration={sw.ElapsedMilliseconds}"); // Работаем с именами string name = "" + (nelements * 2 / 3); //var query2 = namehash_index.GetAllBySample(new object[] { -1, name, -1.0D }); //foreach (var obj in query2) Console.WriteLine(tp_person.Interpret(obj)); //total = 0; //sw.Restart(); //for (int i = 0; i < nprobe; i++) //{ // name = "" + rnd.Next(nelements); // total += namehash_index.GetAllBySample(new object[] { -1, name, -1.0D }).Count(); //} //sw.Stop(); //Console.WriteLine($"GetByNameHash {nprobe} probes. duration={sw.ElapsedMilliseconds} total={total}"); // Работаем с именами и компаратором //name = "" + (nelements / 3); //var query3 = namehash_index_full.GetAllBySample(new object[] { -1, name, -1.0D }); //foreach (var obj in query3) Console.WriteLine(tp_person.Interpret(obj)); //total = 0; //sw.Restart(); //for (int i = 0; i < nprobe; i++) //{ // name = "" + rnd.Next(nelements); // total += namehash_index_full.GetAllBySample(new object[] { -1, name, -1.0D }).Count(); //} //sw.Stop(); //Console.WriteLine($"GetByNameHash Full {nprobe} probes. duration={sw.ElapsedMilliseconds} total={total}"); // Работаем с view индексом name = "" + (nelements * 2 / 3); var query4 = nameview_index.SearchAll(new object[] { -1, name, -1.0D }); foreach (var obj in query4) { Console.WriteLine(tp_person.Interpret(obj)); } nprobe = 1000; total = 0; sw.Restart(); for (int i = 0; i < nprobe; i++) { name = "" + rnd.Next(nelements); total += nameview_index.SearchAll(new object[] { -1, name, -1.0D }).Count(); } sw.Stop(); Console.WriteLine($"IndexView search for {nprobe} probes. duration={sw.ElapsedMilliseconds} total={total}"); }
public static void Demo101() { Console.WriteLine("Start Demo101"); // === Демонстрация базовых действий со структурами === // Создаем тип персоны PType tp_person = new PTypeRecord( new NamedType("id", new PType(PTypeEnumeration.integer)), new NamedType("name", new PType(PTypeEnumeration.sstring)), new NamedType("age", new PType(PTypeEnumeration.integer))); // делаем персону в объектном представлении object ivanov = new object[] { 7001, "Иванов", 20 }; // интерпретируем объект в контексте типа Console.WriteLine(tp_person.Interpret(ivanov, true)); // то же, но без имен полей Console.WriteLine(tp_person.Interpret(ivanov)); Console.WriteLine(); // Создадим поток байтов. Это мог бы быть файл: MemoryStream mstream = new MemoryStream(); // Поработаем через текстовый интерфейс TextWriter tw = new StreamWriter(mstream); TextFlow.Serialize(tw, ivanov, tp_person); tw.Flush(); // Прочитаем то что записали TextReader tr = new StreamReader(mstream); mstream.Position = 0L; string instream = tr.ReadToEnd(); Console.WriteLine($"======== instream={instream}"); Console.WriteLine(); // Теперь десериализуем ivanov = null; mstream.Position = 0L; ivanov = TextFlow.Deserialize(tr, tp_person); // проинтерпретируем объект и посмотрим Console.WriteLine(tp_person.Interpret(ivanov)); Console.WriteLine(); // ===== Последовательности ===== // Создаем тип последовательности персон PType tp_persons = new PTypeSequence(tp_person); // Сделаем генератор персон Random rnd = new Random(); Func <int, IEnumerable <object> > GenPers = nper => Enumerable.Range(0, nper) .Select(i => new object[] { i, "Иванов_" + i, rnd.Next(130) }); // Сгенерируем пробу и проинтерпретируем object sequobj = GenPers(20).ToArray(); Console.WriteLine(tp_persons.Interpret(sequobj)); Console.WriteLine(); // Чем плохо такое решение? Тем, что весь большой объект (последовательность записей) разворачивается в ОЗУ // Более экономным, как правило, является использование последовательностей string dbpath = @"D:/Home/data/GetStarted/"; Stream filestream = new FileStream(dbpath + "db0.bin", FileMode.OpenOrCreate, FileAccess.ReadWrite); UniversalSequenceBase usequence = new UniversalSequenceBase(tp_person, filestream); // Последовательность можно очистить, в нее можно добавлять элементы, в конце добавлений нужно сбросить буфер int npersons = 1_000_000; usequence.Clear(); foreach (object record in GenPers(npersons)) { usequence.AppendElement(record); } usequence.Flush(); // Теперь можно сканировать последовательность int totalages = 0; usequence.Scan((off, ob) => { totalages += (int)((object[])ob)[2]; return(true); }); Console.WriteLine($"total ages = {totalages}"); //// Можно прочитать i-ый элемент //int ind = npersons * 2 / 3; //object ores = usequence.GetByIndex(ind); //Console.WriteLine($"element={tp_person.Interpret(ores)}"); //// Но нет - облом: Размер элемента не фиксирован (есть строка), к таким элементам по индексу обращаться не надо }
public static void Main306() { Console.WriteLine("Start Main306"); // Создадим типы записи и последовательности записей PType tp_rec = new PTypeRecord( new NamedType("id", new PType(PTypeEnumeration.integer)), new NamedType("name", new PType(PTypeEnumeration.sstring)), new NamedType("age", new PType(PTypeEnumeration.integer))); PType tp_seq = new PTypeSequence(tp_rec); // ======== Универсальная последовательность ========== Stream stream = File.Open(datadirectory_path + "data306.bin", FileMode.OpenOrCreate); Stream stream2 = File.Open(datadirectory_path + "keys306.bin", FileMode.OpenOrCreate); Stream stream3 = File.Open(datadirectory_path + "offsets306.bin", FileMode.OpenOrCreate); UniversalSequenceBase sequence = new UniversalSequenceBase(tp_rec, stream); UniversalSequenceBase sequence2 = new UniversalSequenceBase(new PType(PTypeEnumeration.integer), stream2); UniversalSequenceBase sequence3 = new UniversalSequenceBase(new PType(PTypeEnumeration.longinteger), stream3); Random rnd = new Random(); int nelements = 100_000_000; // При заполнении массива, сохраним офсеты элементов в массиве long[] offsets = new long[nelements]; int[] keys = new int[nelements]; bool toload = true; if (toload) { sw.Restart(); sequence.Clear(); for (int i = 0; i < nelements; i++) { int key = nelements - i - 1; offsets[i] = sequence.AppendElement(new object[] { key, "Иванов" + key, rnd.Next(1, 110) }); keys[i] = key; } sequence.Flush(); // отсортируем пару массивов keys, offsets по ключам Array.Sort(keys, offsets); // запишем массивы в последовательности sequence2.Clear(); for (int i = 0; i < nelements; i++) { sequence2.AppendElement(keys[i]); } sequence2.Flush(); sequence3.Clear(); for (int i = 0; i < nelements; i++) { sequence3.AppendElement(offsets[i]); } sequence3.Flush(); sw.Stop(); Console.WriteLine($"Load of {nelements} elements. duration={sw.ElapsedMilliseconds}"); } // Сначала сделаем единичный тест int k = nelements * 2 / 3; long ind = BinarySequenceSearchFirst(0, nelements, k, sequence2); long offf = (long)sequence3.GetByIndex(ind); object rec = sequence.GetElement(offf); Console.WriteLine($"k={k}, v={tp_rec.Interpret(rec)}"); // Будем делать выборку элементов по ключу sw.Restart(); int ntests = 1000; for (int j = 0; j < ntests; j++) { int key = rnd.Next(nelements); long nom1 = BinarySequenceSearchFirst(0, nelements, key, sequence2); long off = (long)sequence3.GetByIndex(nom1); object[] fields = (object[])sequence.GetElement(off); if (key != (int)fields[0]) { throw new Exception("1233eddf"); } } sw.Stop(); Console.WriteLine($"duration of {ntests} tests is {sw.ElapsedMilliseconds} ms."); }
public static void Main302() { Console.WriteLine("Start Main302"); // Создадим типы записи и последовательности записей PType tp_rec = new PTypeRecord( new NamedType("id", new PType(PTypeEnumeration.integer)), new NamedType("name", new PType(PTypeEnumeration.sstring)), new NamedType("age", new PType(PTypeEnumeration.integer))); PType tp_seq = new PTypeSequence(tp_rec); // ======== Универсальная последовательность ========== Stream stream = File.Open(datadirectory_path + "first_data.bin", FileMode.OpenOrCreate); UniversalSequenceBase sequence = new UniversalSequenceBase(tp_rec, stream); Random rnd = new Random(); int nelements = 10_000_000; // Последовательность создается пустой или она может быть очищена sequence.Clear(); // В последовательность можно добавлять элементы в объектном представлении for (int i = 0; i < nelements; i++) { sequence.AppendElement(new object[] { i, "Иванов" + i, rnd.Next(1, 110) }); } // Серию записей обязательно надо завершать сбросом буферов sequence.Flush(); // Изучим полученную последовательность Console.WriteLine($"Count={sequence.Count()}"); foreach (object[] r in sequence.ElementValues().Skip(50_000).Take(20)) { Console.WriteLine($"{r[0]} {r[1]} {r[2]} "); } sw.Restart(); long sum = 0; foreach (object[] r in sequence.ElementValues()) { sum += (int)r[2]; } sw.Stop(); Console.WriteLine($"scan of {nelements} duration {sw.ElapsedMilliseconds} ms. sum={sum}"); sw.Restart(); sum = 0; foreach (object[] r in Enumerable.Range(0, nelements).Select(i => new object[] { i, "Иванов" + i, 55 })) { sum += (int)r[2]; } sw.Stop(); Console.WriteLine($"object flow generation of {nelements} duration {sw.ElapsedMilliseconds} ms. sum={sum}"); sw.Restart(); sum = 0; foreach (var r in Enumerable.Range(0, nelements).Select(i => new AAA() { id = i, name = "Иванов" + i, age = rnd.Next(1, 110) })) { sum += (int)r.age; } sw.Stop(); Console.WriteLine($"struct flow generation of {nelements} duration {sw.ElapsedMilliseconds} ms. sum={sum}"); sw.Restart(); sum = 0; foreach (var r in Enumerable.Range(0, nelements).Select(i => new Tuple <int, string, int>(i, "Иванов" + i, rnd.Next(1, 110)))) { sum += r.Item3; } sw.Stop(); Console.WriteLine($"tuple flow generation of {nelements} duration {sw.ElapsedMilliseconds} ms. sum={sum}"); sw.Restart(); sum = 0; foreach (var r in Enumerable.Range(0, nelements).Select(i => new Tuple <int, long, int>(i, (long)i, rnd.Next(1, 110)))) { sum += r.Item3; } sw.Stop(); Console.WriteLine($"allint tuple flow generation of {nelements} duration {sw.ElapsedMilliseconds} ms. sum={sum}"); sw.Restart(); sum = 0; foreach (var r in Enumerable.Range(0, nelements).Select(i => new object[] { i, (long)i, rnd.Next(1, 110) })) { sum += (int)r[2]; } sw.Stop(); Console.WriteLine($"allint object flow generation of {nelements} duration {sw.ElapsedMilliseconds} ms. sum={sum}"); sw.Restart(); sum = 0; foreach (var r in Enumerable.Range(0, nelements).Select(i => 55)) { sum += (int)r; } sw.Stop(); Console.WriteLine($"int flow generation of {nelements} duration {sw.ElapsedMilliseconds} ms. sum={sum}"); //scan of 10000000 duration 2133 ms.sum = 549806436 //object flow generation of 10000000 duration 858 ms.sum = 550000000 //struct flow generation of 10000000 duration 810 ms.sum=550058422 //tuple flow generation of 10000000 duration 837 ms.sum=549922381 //allint tuple flow generation of 10000000 duration 279 ms.sum=550001434 //allint object flow generation of 10000000 duration 501 ms.sum=549901363 //int flow generation of 10000000 duration 118 ms.sum=550000000 return; // При заполнении массива, сохраним офсеты элементов в массиве long[] offsets = new long[nelements]; int[] keys = new int[nelements]; sequence.Clear(); for (int i = 0; i < nelements; i++) { int key = nelements - i - 1; offsets[i] = sequence.AppendElement(new object[] { key, "Иванов" + key, rnd.Next(1, 110) }); keys[i] = key; } // отсортируем пару массивов keys, offsets по ключам Array.Sort(keys, offsets); // Будем делать выборку элементов по ключу sw.Restart(); int ntests = 10_000; for (int j = 0; j < ntests; j++) { int key = rnd.Next(nelements); int ind = Array.BinarySearch(keys, key); long off = offsets[ind]; object[] fields = (object[])sequence.GetElement(off); //Console.WriteLine($"key={key} {fields[0]} {fields[1]} {fields[2]}"); } sw.Stop(); Console.WriteLine($"duration of {ntests} tests is {sw.ElapsedMilliseconds} ms."); }