示例#1
0
 private void Load(IEnumerable <object> triples)
 {
     table.Clear();
     foreach (object tri in triples)
     {
         long off = table.AppendElement(tri);
     }
     table.Flush();
 }
示例#2
0
        // ==================== Динамика ===================
        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);
        }
示例#3
0
 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();
 }
示例#4
0
 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();
        }
示例#6
0
        // ==================== Динамика ===================

        /// <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);
        }
示例#7
0
        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.");
        }
示例#8
0
        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.");
        }
示例#9
0
        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}");
        }
示例#10
0
        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)}");
            //// Но нет - облом: Размер элемента не фиксирован (есть строка), к таким элементам по индексу обращаться не надо
        }
示例#11
0
        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.");
        }
示例#12
0
        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.");
        }