Exemple #1
0
 public void Flush()
 {
     keyvalue_seq.Flush();
     if (exindexes != null)
     {
         foreach (var exindx in exindexes)
         {
             //exindx.exkeys.Flush();
             //exindx.prikeys.Flush();
             exindx.exprikeys.Flush();
         }
     }
 }
Exemple #2
0
        //static string path = "Databases/";
        public static void Main12()
        {
            string path = "";
            Random rnd  = new Random();

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            Console.WriteLine("Start experiment with UniversalSequense");
            // Тип основной таблицы
            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.real)));
            Stream f1 = File.Open(path + "Databases/f1.bin", FileMode.OpenOrCreate);
            UniversalSequence <int> keyvalue_seq = new UniversalSequence <int>(tp_person, f1);
            // Теперь надо добавить индекс и использовать его
            Func <object[], int> keyFunc = (object[] re) => (int)re[0];
            // вводим индекс
            Stream f2 = File.Open(path + "Databases/f2.bin", FileMode.OpenOrCreate);
            Stream f3 = File.Open(path + "Databases/f3.bin", FileMode.OpenOrCreate);
            UniversalSequence <int>  keys    = new UniversalSequence <int>(new PType(PTypeEnumeration.integer), f2);
            UniversalSequence <long> offsets = new UniversalSequence <long>(new PType(PTypeEnumeration.longinteger), f3);

            int nelements = 10_000_000;

            Console.WriteLine($"Sequence of {nelements} elements");
            bool toload = true;

            int[]  k_arr = new int[nelements];
            long[] o_arr = null;
            if (toload)
            {
                sw.Restart();
                keyvalue_seq.Clear();
                var query = Enumerable.Range(0, nelements).Select(i => new object[] { nelements - i - 1, "" + (nelements - i - 1), 33.3 });
                o_arr = new long[nelements];
                int pos = 0;
                foreach (var el in query)
                {
                    long off = keyvalue_seq.AppendElement(el);
                    k_arr[pos] = keyFunc(el);
                    o_arr[pos] = off;
                    pos++;
                }
                keyvalue_seq.Flush();
                // Сортировка
                Array.Sort(k_arr, o_arr);
                // Надо записать массивы
                keys.Clear();
                offsets.Clear();
                for (int i = 0; i < nelements; i++)
                {
                    keys.AppendElement(k_arr[i]);
                    offsets.AppendElement(o_arr[i]);
                }
                keys.Flush();
                offsets.Flush();
                o_arr = null;
                sw.Stop();
                Console.WriteLine($"Load ok. duration={sw.ElapsedMilliseconds}");
            }
            else
            {
                // Надо прочитать массивы
                for (int i = 0; i < nelements; i++)
                {
                    object ob = i == 0 ? keys.GetElement(keys.ElementOffset(0L)) : keys.GetElement();
                    k_arr[i] = (int)ob;
                    //object ob2 = i == 0 ? offsets.GetElement(offsets.ElementOffset(0L)) : offsets.GetElement();
                    //o_arr[i] = (long)ob2;
                }
            }

            int k1 = nelements * 2 / 3;

            int nprobe = 10_000;

            sw.Restart();
            // Прямая выборка
            for (int i = 0; i < nprobe; i++)
            {
                int k2  = rnd.Next(nelements);
                int ind = Array.BinarySearch(k_arr, k2);
                //long offset = o_arr[ind];
                long offset = (long)offsets.GetElement(offsets.ElementOffset(ind));
                var  r      = (object[])keyvalue_seq.GetElement(offset);
            }
            sw.Stop();
            Console.WriteLine($"BinarySearch and GetElement ({nprobe} times). duration={sw.ElapsedMilliseconds}");

            /*
             * // Собственно таблица
             * TableView tab_person = new TableView(path + "person", tp_person);
             * Func<object, int> person_code_keyproducer = v => (int)((object[])((object[])v)[1])[0];
             * IndexKeyImmutable<int> ind_arr_person = new IndexKeyImmutable<int>(path + "person_ind")
             * {
             *  Table = tab_person,
             *  KeyProducer = person_code_keyproducer,
             *  Scale = null
             * };
             * //ind_arr_person.Scale = new ScaleCell(path + "person_ind") { IndexCell = ind_arr_person.IndexCell };
             * IndexDynamic<int, IndexKeyImmutable<int>> index_person = new IndexDynamic<int, IndexKeyImmutable<int>>(true)
             * {
             *  Table = tab_person,
             *  IndexArray = ind_arr_person,
             *  KeyProducer = person_code_keyproducer
             * };
             * tab_person.RegisterIndex(index_person);
             *
             * int nelements = 1000000;
             * bool toload = true; // Загружать или нет новую базу данных
             * if (toload)
             * {
             *  sw.Restart();
             *  // Очистим ячейки последовательности и индекса
             *  tab_person.Clear();
             *
             *  IEnumerable<object> flow = Enumerable.Range(0, nelements)
             *      .Select(i =>
             *      {
             *          int id = nelements - i;
             *          string name = "=" + id.ToString() + "=";
             *          double age = rnd.NextDouble() * 100.0;
             *          return new object[] { id, name, age };
             *      });
             *  tab_person.Fill(flow);
             *
             *  // Теперь надо отсортировать индексный массив по ключу
             *  tab_person.BuildIndexes();
             *  sw.Stop();
             *  Console.WriteLine("Load ok. duration for {0} elements: {1} ms", nelements, sw.ElapsedMilliseconds);
             * }
             *
             * // Проверим работу
             * int search_key = nelements * 2 / 3;
             * var ob = index_person.GetAllByKey(search_key)
             *  .Select(ent => ((object[])ent.Get())[1])
             *  .FirstOrDefault();
             * if (ob == null) throw new Exception("Didn't find person " + search_key);
             * Console.WriteLine("Person {0} has name {1}", search_key, ((object[])ob)[1]);
             *
             * // Засечем скорость выборок
             * sw.Restart();
             * for (int i = 0; i < 1000; i++)
             * {
             *  search_key = rnd.Next(nelements) + 1;
             *  ob = index_person.GetAllByKey(search_key)
             *      .Select(ent => ((object[])ent.Get())[1])
             *      .FirstOrDefault();
             *  if (ob == null) throw new Exception("Didn't find person " + search_key);
             *  string nam = (string)((object[])ob)[1];
             * }
             * sw.Stop();
             * Console.WriteLine("Duration for 1000 search in {0} elements: {1} ms", nelements, sw.ElapsedMilliseconds);
             */
        }
Exemple #3
0
 public void Flush()
 {
     table.Flush();
     str_offsets.Flush();
 }
Exemple #4
0
        public void CalculateStaticIndex()
        {
            if (dic1 != null)
            {
                dic1 = new Dictionary <int, long>();              // Не используем накопленное содержание
            }
            if (dic2 != null)
            {
                dic2 = new Dictionary <int, long>();
            }
            int ind       = 0;
            int nelements = (int)keyvalue_seq.Count();

            keys_arr = new int[nelements];
            long[] offs_arr = new long[nelements];
            keyvalue_seq.Scan((off, obj) =>
            {
                int key       = (int)((object[])obj)[0];
                keys_arr[ind] = key;
                offs_arr[ind] = off;
                ind++;
                return(true);
            });
            Array.Sort(keys_arr, offs_arr);
            keys.Clear(); //keys.Fill(new object[0]);
            List <int> keys_list = new List <int>();

            offsets.Clear(); //offsets.Fill(new object[0]);
            // Будем убирать повторы
            int  prev_key    = Int32.MaxValue;
            long prev_offset = Int64.MinValue;

            for (int i = 0; i < nelements; i++)
            {
                int  key    = keys_arr[i];
                long offset = offs_arr[i];
                if (key != prev_key)
                {  // Надо сохранить пару, но только если предыдущий ключ не фиктивный
                    if (prev_key != Int32.MaxValue)
                    {
                        keys.AppendElement(prev_key);
                        keys_list.Add(prev_key);
                        offsets.AppendElement(prev_offset);
                    }
                    prev_key    = key;
                    prev_offset = offset;
                }
                else
                {
                    if (offset > prev_offset)
                    {
                        prev_offset = offset;
                    }
                }
            }
            if (nelements > 0)
            {
                keys.AppendElement(prev_key);
                keys_list.Add(prev_key);
                offsets.AppendElement(prev_offset);
            }

            // Доделаем массив ключей
            keys_arr = keys_list.ToArray();
            keys.Flush();
            offsets.Flush();

            // Внешние индексы, если есть
            if (exindexes != null)
            {
                foreach (var exindx in exindexes)
                {
                    //var q = exindx.exkeys;
                    //// long[] offs_arr = new long[nelements];
                    //int[] ext_arr = exindx.exkeys.ElementValues().Cast<int>().ToArray();
                    //int[] pri_arr = exindx.prikeys.ElementValues().Cast<int>().ToArray();
                    //Array.Sort(ext_arr, pri_arr);
                    //exindx.exkeys.Clear(); //exindx.exkeys.Fill(new object[0]);
                    //foreach (int k in ext_arr) exindx.exkeys.AppendElement(k);
                    //exindx.prikeys.Clear(); //exindx.prikeys.Fill(new object[0]);
                    //foreach (int k in pri_arr) exindx.prikeys.AppendElement(k);
                    //exindx.exkeys.Flush();
                    //exindx.prikeys.Flush();
                    long  ne      = exindx.exprikeys.Count();
                    int[] ext_arr = new int[ne];
                    int[] pri_arr = new int[ne];
                    for (int i = 0; i < ne; i++)
                    {
                        object[] ep = (object[])exindx.exprikeys.GetElement(exindx.exprikeys.ElementOffset(i));
                        ext_arr[i] = (int)ep[0];
                        pri_arr[i] = (int)ep[1];
                    }
                    Array.Sort(ext_arr, pri_arr);
                    exindx.exprikeys.Clear();
                    for (int i = 0; i < ne; i++)
                    {
                        exindx.exprikeys.AppendElement(new object[] { ext_arr[i], pri_arr[i] });
                    }
                    exindx.exprikeys.Flush();

                    pri_arr        = null;
                    exindx.key_arr = ext_arr;
                }
            }
        }