Example #1
0
 public void Load(IEnumerable <object> flow)
 {
     Clear();
     foreach (object element in flow)
     {
         sequence.AppendElement(element);
     }
     sequence.Flush();
     Build();
 }
Example #2
0
        public void Load(int[] keys)
        {
            keysLength = keys.Length;
            if (keysLength == 0)
            {
                return;
            }
            n_scale = keysLength / 16;
            min     = keys[0];
            max     = keys[keysLength - 1];

            // Особый случай, когда n_scale < 1 или V_min == V_max. Тогда делается массив из одного элемента и особая функция
            if (n_scale < 1 || min == max)
            {
                n_scale   = 1;
                starts    = new int[1];
                starts[0] = 0;
            }
            else
            {
                starts = new int[n_scale];
            }
            SetToPosition();
            // Заполнение количеств элементов в диапазонах
            for (int i = 0; i < keys.Length; i++)
            {
                int key      = keys[i];
                int position = ToPosition(key);
                // Предполагаю, что начальная разметка массива - нули
                starts[position] += 1;
            }
            // Заполнение начал диапазонов
            int sum = 0;

            for (int i = 0; i < n_scale; i++)
            {
                int num_els = starts[i];
                starts[i] = sum;
                sum      += num_els;
            }
            SetGetDia();
            // Запись наработанного в стрим
            keylengthminmaxstarts.Clear();
            keylengthminmaxstarts.AppendElement(keysLength);
            keylengthminmaxstarts.AppendElement(min);
            keylengthminmaxstarts.AppendElement(max);
            for (int i = 0; i < starts.Length; i++)
            {
                keylengthminmaxstarts.AppendElement(starts[i]);
            }
            keylengthminmaxstarts.Flush();
        }
Example #3
0
        public void Build()
        {
            // формируем массив пар
            List <int>  keys    = new List <int>();
            List <long> offsets = new List <long>();

            int ind = 0;

            bearing.Scan((off, obj) =>
            {
                foreach (int key in keyFun(obj))
                {
                    offsets.Add(off);
                    keys.Add(key);
                    ind++;
                }
                return(true);
            });
            int[]  keys_arr    = keys.ToArray(); keys = null;
            long[] offsets_arr = offsets.ToArray(); offsets = null;
            // Сортируем по ключу
            Array.Sort(keys_arr, offsets_arr);

            // Эта часть делается если компаратор объектов comp задан
            //if (comp != null)
            //{
            //    // массив объектов
            //    List<object> objs = new List<object>();
            //    // проходим по массиву ключей, в группах одинаковых ключей выделяем массив объектов
            //    int key, start = -1; // начало интервала и количество с одинаковым ключом
            //    key = Int32.MinValue;
            //    Action fixgroup = () =>
            //    {
            //        int number = objs.Count;
            //        if (number > 1)
            //        {
            //            long[] offs_small = new long[number];
            //            for (int j = 0; j < number; j++)
            //                offs_small[j] = offsets[start + j];
            //            // Сортировка отрезка
            //            Array.Sort(objs.ToArray(), offs_small, comp);
            //            // вернуть отсортированные офсеты на место
            //            for (int j = 0; j < number; j++)
            //                offsets[start + j] = offs_small[j];
            //        }
            //    };
            //    for (int i = 0; i < ne; i++)
            //    {
            //        object ob = bearing.GetElement(offsets[i]);
            //        int k = keyFun(ob);
            //        // смена ключа
            //        if (i == 0 || k != key)
            //        {
            //            // фиксируем предыдущий отрезок (key, start, number)
            //            //FixGroup(offsets, objs, start);
            //            fixgroup();
            //            // Начать новый отрезок
            //            key = k;
            //            start = i;
            //            objs.Clear();
            //        }
            //        // основное действие
            //        objs.Add(ob);
            //    }
            //    if (objs.Count > 1) fixgroup();
            //}

            // Записываем
            keyoffsets.Clear(); // очищаем
            for (int i = 0; i < keys_arr.Length; i++)
            {
                keyoffsets.AppendElement(new object[] { keys_arr[i], offsets_arr[i] });
            }
            keyoffsets.Flush();

            if (scale != null)
            {
                scale.Load(keys_arr);
            }
        }
Example #4
0
        public void Build()
        {
            // формируем массив пар
            int ne = (int)bearing.Count();

            //KeyOffPair[] keyoff_arr = new KeyOffPair[ne];
            int[]  keys    = new int[ne];
            long[] offsets = new long[ne];

            int ind = 0;

            bearing.Scan((off, obj) =>
            {
                offsets[ind] = off;
                keys[ind]    = keyFun(obj);
                ind++;
                return(true);
            });
            // Сортируем по ключу
            Array.Sort(keys, offsets);

            // Эта часть делается если компаратор объектов comp задан
            if (comp != null)
            {
                // массив объектов
                List <object> objs = new List <object>();
                // проходим по массиву ключей, в группах одинаковых ключей выделяем массив объектов
                int key, start = -1; // начало интервала и количество с одинаковым ключом
                key = Int32.MinValue;
                Action fixgroup = () =>
                {
                    int number = objs.Count;
                    if (number > 1)
                    {
                        long[] offs_small = new long[number];
                        for (int j = 0; j < number; j++)
                        {
                            offs_small[j] = offsets[start + j];
                        }
                        // Сортировка отрезка
                        Array.Sort(objs.ToArray(), offs_small, comp);
                        // вернуть отсортированные офсеты на место
                        for (int j = 0; j < number; j++)
                        {
                            offsets[start + j] = offs_small[j];
                        }
                    }
                };
                for (int i = 0; i < ne; i++)
                {
                    object ob = bearing.GetElement(offsets[i]);
                    int    k  = keyFun(ob);
                    // смена ключа
                    if (i == 0 || k != key)
                    {
                        // фиксируем предыдущий отрезок (key, start, number)
                        //FixGroup(offsets, objs, start);
                        fixgroup();
                        // Начать новый отрезок
                        key   = k;
                        start = i;
                        objs.Clear();
                    }
                    // основное действие
                    objs.Add(ob);
                }
                if (objs.Count > 1)
                {
                    fixgroup();
                }
            }

            // Записываем
            keyoffsets.Clear(); // очищаем
            for (int i = 0; i < keys.Length; i++)
            {
                keyoffsets.AppendElement(new object[] { keys[i], offsets[i] });
            }
            keyoffsets.Flush();

            if (scale != null)
            {
                scale.Load(keys);
            }
        }
Example #5
0
        public void Build()
        {
            // формируем массив пар
            List <int>  keys_list    = new List <int>();
            List <long> offsets_list = new List <long>();

            bearing.Scan((off, obj) =>
            {
                if (applicable(obj))
                {
                    int hash = hashFun(obj);
                    keys_list.Add(hash);
                    offsets_list.Add(off);
                }
                return(true);
            });
            int[] keys = keys_list.ToArray();
            keys_list = null;
            long[] offsets = offsets_list.ToArray();
            offsets_list = null;
            int ne = keys.Length;

            // Сортируем по ключу
            Array.Sort(keys, offsets);

            // Эта часть делается если компаратор объектов comp задан
            // Производится сортировка участков с одинаковыми ключами
            if (comp != null)
            {
                // массив в который будет вкладываться набор объектов с одинаковыми ключами
                List <object> objs = new List <object>();
                // проходим по массиву ключей, в группах одинаковых ключей выделяем массив объектов
                int key, start = -1; // ключ интервала и начало интервала в массивах keys и offsets
                key = Int32.MinValue;
                // Фиксация накопленного в предыдущих переменных objs, key, start
                Action fixgroup = () =>
                {
                    int number = objs.Count;
                    if (number > 1)
                    {
                        long[] offs_small = new long[number];
                        for (int j = 0; j < number; j++)
                        {
                            offs_small[j] = offsets[start + j];
                        }
                        // Сортировка отрезка
                        Array.Sort(objs.ToArray(), offs_small, comp);
                        // вернуть отсортированные офсеты на место
                        for (int j = 0; j < number; j++)
                        {
                            offsets[start + j] = offs_small[j];
                        }
                    }
                };
                // Сканирование массивов keys, offsets
                for (int i = 0; i < ne; i++)
                {
                    int k = keys[i];
                    // смена ключа
                    if (i == 0 || k != key)
                    {
                        // фиксируем предыдущий отрезок (key, start), начинаем новый
                        fixgroup();
                        // Начать новый отрезок
                        key   = k;
                        start = i;
                        objs.Clear();
                    }
                    // основное действие
                    object ob = bearing.GetItem(offsets[i]);
                    objs.Add(ob);
                }
                if (objs.Count > 1)
                {
                    fixgroup();
                }
            }

            // Записываем
            keyoffsets.Clear(); // очищаем
            for (int i = 0; i < keys.Length; i++)
            {
                keyoffsets.AppendElement(new object[] { keys[i], offsets[i] });
            }
            keyoffsets.Flush();

            //if (scale != null && keys.Length == 0) scale = null;
            if (scale != null)
            {
                scale.Load(keys);
            }
            keys    = null;
            offsets = null;
            System.GC.Collect();
        }
Example #6
0
        private object[] rare_elements = null; // --


        public void Build()
        {
            // Формируем последовательность offset_sequ
            offset_sequ.Clear();
            bearing.Scan((off, obj) =>
            {
                bool isapp = applicable(obj);
                if (applicable(obj))
                {
                    offset_sequ.AppendElement(off);
                }
                return(true);
            });
            offset_sequ.Flush();
            // Возможно, нам понадобятся два дополнительных стрима
            FileStream tmp_stream1 = null;
            FileStream tmp_stream2 = null;

            // Определяем рекурсивный метод построения Bld(long start_ind, long number) который в итоге переупорядочивает
            // отрезок последовательности offset_sequ так, что ссылаемые элементы становятся отсортированными.
            void Bld(long start_ind, long number)
            {
                if (number <= volume_of_offset_array)
                {
                    long[]   offsets  = new long[number];
                    object[] elements = new object[number];
                    // берем в массивы
                    for (long i = 0; i < number; i++)
                    {
                        long off = (long)offset_sequ.GetByIndex(start_ind + i);
                        offsets[i]  = off;
                        elements[i] = bearing.GetItem(off);
                    }
                    // Сортируем
                    Array.Sort(elements, offsets, comp_default);
                    // кладем из массивов в последовательность
                    for (long i = 0; i < number; i++)
                    {
                        if (i == 0)
                        {
                            offset_sequ.SetElement(offsets[i], offset_sequ.ElementOffset(start_ind));
                        }
                        else
                        {
                            offset_sequ.SetElement(offsets[i]);
                        }
                    }
                }
                else
                {
                    // надо разбить отрезок на два, в каждом сделать сортировку, а результаты слить.
                    long firsthalf_start   = start_ind;
                    long firsthalf_number  = number / 2;
                    long secondhalf_start  = start_ind + firsthalf_number;
                    long secondhalf_number = number - firsthalf_number;

                    Bld(firsthalf_start, firsthalf_number);
                    Bld(secondhalf_start, secondhalf_number);

                    if (tmp_stream1 == null)
                    {
                        tmp_stream1 = File.Open(tmpdir + "tmp1.$$$", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    }
                    if (tmp_stream2 == null)
                    {
                        tmp_stream2 = File.Open(tmpdir + "tmp2.$$$", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    }
                    tmp_stream1.Position = 0L;
                    tmp_stream2.Position = 0L;

                    byte[] buffer = new byte[buffersize];

                    Stream source1 = offset_sequ.Media;
                    source1.Position = 8 + firsthalf_start * 8;
                    long nbytes1 = firsthalf_number * 8;
                    while (nbytes1 > 0)
                    {
                        int nb = source1.Read(buffer, 0, nbytes1 >= buffer.Length ? buffer.Length : (int)nbytes1);
                        tmp_stream1.Write(buffer, 0, nb);
                        nbytes1 -= nb;
                    }
                    Stream source2 = offset_sequ.Media;
                    source2.Position = 8 + secondhalf_start * 8;
                    long nbytes2 = secondhalf_number * 8;
                    while (nbytes2 > 0)
                    {
                        int nb = source2.Read(buffer, 0, nbytes2 >= buffer.Length ? buffer.Length : (int)nbytes2);
                        tmp_stream2.Write(buffer, 0, nb);
                        nbytes2 -= nb;
                    }
                    tmp_stream1.Position = 0L;
                    BinaryReader br1  = new BinaryReader(tmp_stream1);
                    long         off1 = br1.ReadInt64();
                    object       obj1 = bearing.GetItem(off1);
                    long         nom1 = 0; // номер обрабатываемого элемента
                    tmp_stream2.Position = 0L;
                    BinaryReader br2     = new BinaryReader(tmp_stream2);
                    long         off2    = br2.ReadInt64();
                    object       obj2    = bearing.GetItem(off2);
                    long         nom2    = 0; // номер обрабатываемого элемента
                    long         out_ind = start_ind;
                    while (nom1 < firsthalf_number && nom2 < secondhalf_number)
                    {
                        if (comp_default.Compare(obj1, obj2) <= 0)
                        {
                            offset_sequ.SetElement(off1, offset_sequ.ElementOffset(out_ind));
                            nom1++;
                            if (nom1 < firsthalf_number)
                            {
                                off1 = br1.ReadInt64();
                                obj1 = bearing.GetItem(off1);
                            }
                        }
                        else
                        {
                            offset_sequ.SetElement(off2, offset_sequ.ElementOffset(out_ind));
                            nom2++;
                            if (nom2 < secondhalf_number)
                            {
                                off2 = br2.ReadInt64();
                                obj2 = bearing.GetItem(off2);
                            }
                        }
                        out_ind++;
                    }
                    // Перепись остатков
                    if (nom1 < firsthalf_number)
                    {
                        for (long ii = nom1; ii < firsthalf_number; ii++)
                        {
                            if (ii != nom1)
                            {
                                off1 = br1.ReadInt64();
                            }
                            offset_sequ.SetElement(off1, offset_sequ.ElementOffset(out_ind));
                            out_ind++;
                        }
                    }
                    else if (nom2 < secondhalf_number)
                    {
                        for (long ii = nom2; ii < secondhalf_number; ii++)
                        {
                            if (ii != nom2)
                            {
                                off2 = br2.ReadInt64();
                            }
                            offset_sequ.SetElement(off2, offset_sequ.ElementOffset(out_ind));
                            out_ind++;
                        }
                    }
                }
            };

            // Исполним
            Bld(0L, offset_sequ.Count());

            if (tmp_stream1 != null)
            {
                tmp_stream1.Close();
                File.Delete(tmpdir + "tmp1.$$$");
            }
            if (tmp_stream2 != null)
            {
                tmp_stream2.Close();
                File.Delete(tmpdir + "tmp2.$$$");
            }
            Refresh();
        }