Пример #1
0
        public TripleStore32(Func <Stream> stream_gen, string tmp_dir)
        {
            // Тип Object Variants
            PType tp_ov = new PTypeUnion(
                new NamedType("dummy", new PType(PTypeEnumeration.none)),
                new NamedType("iri", new PType(PTypeEnumeration.integer)),
                new NamedType("str", new PType(PTypeEnumeration.sstring)));

            tp_triple = new PTypeRecord(
                new NamedType("subj", new PType(PTypeEnumeration.integer)),
                new NamedType("pred", new PType(PTypeEnumeration.integer)),
                new NamedType("obj", tp_ov));
            table = new UniversalSequenceBase(tp_triple, stream_gen());
            var spo_comparer = Comparer <object> .Create(new Comparison <object>((object a, object b) =>
            {
                object[] aa = (object[])a; object[] bb = (object[])b;
                int cmp = ((int)aa[0]).CompareTo((int)bb[0]);
                return(cmp);
            }));

            keyFunc   = tri => (int)((object[])tri)[0];
            index_spo = new UniversalSequenceCompKey32(stream_gen(), keyFunc, spo_comparer, table);
            indexTest = new IndexViewImmutable(stream_gen, table,
                                               Comparer <object> .Create(new Comparison <object>((object a, object b) =>
            {
                object[] aa = (object[])a; object[] bb = (object[])b;
                int cmp     = ((int)aa[0]).CompareTo((int)bb[0]);
                return(cmp);
            })), tmp_dir, 20_000_000
                                               );
        }
Пример #2
0
        public Nametable32(Func <Stream> stream_gen)
        {
            PType tp_elem = new PTypeRecord(
                new NamedType("code", new PType(PTypeEnumeration.integer)),
                new NamedType("str", new PType(PTypeEnumeration.sstring)));

            cod_str   = new UniversalSequenceBase(tp_elem, stream_gen());
            offsets   = new UniversalSequenceBase(new PType(PTypeEnumeration.longinteger), stream_gen());
            index_str = new IndexKey32CompImmutable(stream_gen, cod_str, ob => true,
                                                    ob => Hashfunctions.HashRot13((string)((object[])ob)[1]), null);
            dyna_index = new Dictionary <string, int>();
        }
        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();
        }
Пример #4
0
        // Конструктор
        public Mag_Triple_Store(Stream tab_stream, Stream spo_stream, Comparer <object> comp)
        {
            this.spo_comparer = comp;
            tp_triple         = new PTypeRecord(
                new NamedType("subj", new PType(PTypeEnumeration.integer)),
                new NamedType("pred", new PType(PTypeEnumeration.integer)),
                new NamedType("obj", tp_ov));
            table        = new UniversalSequenceBase(tp_triple, tab_stream);
            spo_comparer = Comparer <object> .Create(new Comparison <object>((object a, object b) =>
            {
                object[] aa = (object[])a; object[] bb = (object[])b;
                int cmp = ((int)aa[0]).CompareTo((int)bb[0]);
                return(cmp);
            }));

            index_spo = new UniversalSequenceComp(new PType(PTypeEnumeration.longinteger), spo_stream, spo_comparer, table);
        }
Пример #5
0
        public Nametable32(Func <Stream> stream_gen)
        {
            PType tp_elem = new PTypeRecord(
                new NamedType("code", new PType(PTypeEnumeration.integer)),
                new NamedType("str", new PType(PTypeEnumeration.sstring)));

            table       = new UniversalSequenceBase(tp_elem, stream_gen());
            str_offsets = new UniversalSequence <long>(new PType(PTypeEnumeration.longinteger), stream_gen());
            Comparer <object> comp_str = 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));
            }));

            name_index = new IndexKey32CompImm(stream_gen, table,
                                               ob => Hashfunctions.HashRot13((string)((object[])ob)[1]), comp_str);
            dyna_index = new Dictionary <string, int>();
        }
Пример #6
0
        public TripleStoreInt32_(Func <Stream> stream_gen)
        {
            // Тип Object Variants
            PType tp_ov = new PTypeUnion(
                new NamedType("dummy", new PType(PTypeEnumeration.none)),
                new NamedType("iri", new PType(PTypeEnumeration.integer)),
                new NamedType("str", new PType(PTypeEnumeration.sstring)));
            PType tp_triple = new PTypeRecord(
                new NamedType("subj", new PType(PTypeEnumeration.integer)),
                new NamedType("pred", new PType(PTypeEnumeration.integer)),
                new NamedType("obj", tp_ov));

            table   = new UniversalSequenceBase(tp_triple, stream_gen());
            s_index = new IndexKey32CompImm(stream_gen, table, ob => (int)((object[])ob)[0], null);
            string             selected_chars = "!\"#$%&\'()*+,-./0123456789:;<=>?@abcdefghjklmnopqrstuwxyz{|}~абвгдежзийклмнопрстуфхцчшщъыьэюяё";
            Func <object, int> halfKeyFun     = ob =>
            {
                object[] tri  = (object[])ob;
                object[] pair = (object[])tri[2];
                int      tg   = (int)pair[0];
                if (tg == 1) // iri
                {
                    return(1 - (int)pair[1]);
                }
                else if (tg == 2) // str
                {
                    string s   = (string)pair[1];
                    int    len = s.Length;
                    var    chs = s.ToCharArray()
                                 .Concat(Enumerable.Repeat(' ', len < 4 ? 4 - len : 0))
                                 .Take(4)
                                 .Select(ch =>
                    {
                        int ind = selected_chars.IndexOf(ch);
                        if (ind == -1)
                        {
                            ind = 0;                // неизвестный символ помечается как '!'
                        }
                        return(ind);
                    }).ToArray();
                    return((chs[0] << 24) | (chs[1] << 16) | (chs[2] << 8) | chs[3]);
                }
                throw new Exception("Err: 292333");
            };

            Test_keyfun = halfKeyFun;
            Comparer <object> comp = Comparer <object> .Create(new Comparison <object>((object a, object b) =>
            {
                object[] aa = (object[])((object[])a)[2];
                object[] bb = (object[])((object[])b)[2];
                int a1 = (int)aa[0];
                int b1 = (int)bb[0];
                int cmp = a1.CompareTo(b1);
                if (cmp != 0)
                {
                    return(cmp);
                }
                if (a1 == 1)
                {
                    return(((int)aa[1]).CompareTo(((int)bb[1])));
                }
                return(((string)aa[1]).CompareTo(((string)bb[1])));
            }));

            o_index = new IndexKey32CompImm(stream_gen, table, halfKeyFun, comp);
        }
Пример #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 TripleStoreInt32(Func <Stream> stream_gen)
        {
            // сначала таблица имен
            nt = new Nametable32(stream_gen);
            // Тип Object Variants
            PType tp_ov = new PTypeUnion(
                new NamedType("dummy", new PType(PTypeEnumeration.none)),
                new NamedType("iri", new PType(PTypeEnumeration.integer)),
                new NamedType("str", new PType(PTypeEnumeration.sstring)),
                new NamedType("int", new PType(PTypeEnumeration.sstring)),
                new NamedType("date", new PType(PTypeEnumeration.sstring)),
                new NamedType("langstr", new PTypeRecord(
                                  new NamedType("lang", new PType(PTypeEnumeration.sstring)),
                                  new NamedType("str", new PType(PTypeEnumeration.sstring)))));
            PType tp_triple = new PTypeRecord(
                new NamedType("subj", new PType(PTypeEnumeration.integer)),
                new NamedType("pred", new PType(PTypeEnumeration.integer)),
                new NamedType("obj", tp_ov));

            // Главная последовательность кодированных триплетов
            table = new UniversalSequenceBase(tp_triple, stream_gen());

            // прямой ссылочный индекс
            s_index = new IndexKey32CompImmutable(stream_gen, table,
                                                  ob => Enumerable.Repeat <int>((int)((object[])ob)[0], 1), null);

            // Обратный ссылочный индекс
            i_index = new IndexKey32Imm(stream_gen, table, obj =>
            {
                object[] pair = (object[])((object[])obj)[2];
                int tg        = (int)pair[0];
                if (tg != 1)
                {
                    return(Enumerable.Empty <int>());
                }
                return(Enumerable.Repeat <int>((int)pair[1], 1));
            }, null);

            // Индекс по тексту объектов триплетов с предикатом http://fogid.net/o/name
            Comparer <object> comp = Comparer <object> .Create(new Comparison <object>((object a, object b) =>
            {
                return(string.Compare((string)((object[])((object[])a)[2])[1], (string)((object[])((object[])b)[2])[1]));
            }));

            int name_code = Int32.MinValue; // nt.GetSetStr("http://fogid.net/o/name"); // Такое предварительное вычисление не работает!!!

            name_index = new IndexKey32CompImmutable(stream_gen, table, obj =>
            {
                if (name_code == Int32.MinValue)
                {
                    name_code = nt.GetSetStr("http://fogid.net/o/name");
                }
                object[] tri = (object[])obj;
                //TODO: кодов имени может быть много...
                if ((int)tri[1] != name_code)
                {
                    return(Enumerable.Empty <int>());
                }
                object[] pair = (object[])tri[2];
                int tg        = (int)pair[0];
                string data   = null;
                if (tg == 2)
                {
                    data = (string)pair[1];
                }
                //else if (tg == 5) data = (string)((object[])pair[1])[1]; // пока будем работать только с простыми строками
                if (data != null)
                {
                    return(Enumerable.Repeat <int>(Hashfunctions.First4charsRu(data), 1));
                }
                return(Enumerable.Empty <int>());
            },
                                                     //new int[] { Hashfunctions.First4charsRu((string)((object[])obj)[1]) }
                                                     comp);
        }
Пример #9
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.");
        }
Пример #10
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}");
        }
Пример #11
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)}");
            //// Но нет - облом: Размер элемента не фиксирован (есть строка), к таким элементам по индексу обращаться не надо
        }
Пример #12
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.");
        }
Пример #13
0
        // 10 тыс. элементов загрузка 5.4 сек. выборка 1 тыс. 97 мсек.
        // 100 тыс. элементов загрузка 71 сек. выборка 1 тыс. 25 сек.

        private static long BinarySequenceSearchFirst(long start, long number, int key, UniversalSequenceBase seq)
        {
            long half            = number / 2;
            int  middle_keyvalue = (int)seq.GetByIndex(start + half);

            if (half == 0) // number = 0, 1
            {
                if ((int)seq.GetByIndex(start) == key)
                {
                    return(start);
                }
                else if ((int)seq.GetByIndex(start + 1) == key)
                {
                    return(start + 1);
                }
                else
                {
                    return(-1);
                }
            }
            if (middle_keyvalue == key)
            {
                return(start + half);
            }

            long middle       = start + half;
            long rest         = number - half - 1;
            var  middle_depth = middle_keyvalue - key;

            if (middle_depth == 0) // Нашли!
            {
                return(middle);
            }
            if (middle_depth < 0)
            {
                return(BinarySequenceSearchFirst(middle + 1, rest, key, seq));
            }
            else
            {
                return(BinarySequenceSearchFirst(start, half, key, seq));
            }
        }
Пример #14
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.");
        }