private static void Load(PaCell cell) { cell.Clear(); cell.Fill(new object[0]); for (int i = 0; i < 1000*1024*1024; i++) { cell.Root.AppendElement(i); } cell.Flush(); }
private static void Main(string[] args) { string _path = "../../"; if (System.IO.File.Exists(_path + "cnf.xml")) { var xcnf = System.Xml.Linq.XElement.Load(_path + "cnf.xml"); count = Int64.Parse(xcnf.Element("count").Value); } else { var xcnf = System.Xml.Linq.XElement.Parse(@"<cnf><count>10000000</count></cnf>"); xcnf.Save(_path + "cnf.xml"); } Stopwatch timer=new Stopwatch(); PaCell sequnceCell = new PaCell(new PTypeSequence(new PType(PTypeEnumeration.longinteger)), "../../../Databases/sequnce for sort.pa", false); sequnceCell.Clear(); timer.Start(); sequnceCell.Fill(new object[0]); Random r = new Random(); for (long i = 0L; i < count; i++) { sequnceCell.Root.AppendElement(count - i); } sequnceCell.Flush(); timer.Stop(); Console.WriteLine("created " + timer.Elapsed.TotalSeconds+"sec."); timer.Restart(); sequnceCell.Root.SortByKey<long, long>(0, (ulong) sequnceCell.Root.Count(), l => l, row=>(long)row, l => (object)l, null); timer.Stop(); Console.WriteLine("sorted " + timer.Elapsed.TotalSeconds + "sec."); Console.WriteLine(string.Join(", ", sequnceCell.Root.ElementValues(0, 20))); var query1 = sequnceCell.Root.BinarySearchFirst(entry => (int) ((long) entry.Get() - count/2)); if (query1.IsEmpty) Console.WriteLine("search of first empty"); Console.WriteLine("search of first end"); var query = sequnceCell.Root.BinarySearchAll(ent => (int) ((long) ent.Get() - count/2)).ToArray(); if(!query.Any()) Console.WriteLine("search of all empty"); Console.WriteLine("search of all end"); //while (sequnceCell.Root.State!=PaSequenceEntry.StateEnum.Ready) //{ //} timer.Restart(); long old = (long)sequnceCell.Root.Element(0).Get(); for (long i = 1; i < count; i++) { long entry2 = (long)sequnceCell.Root.Element(i).Get(); if (old > entry2) Console.WriteLine("error"); old = entry2; if (i % 100000000 == 0) Console.WriteLine(((double)i) / count * 100); } timer.Stop(); Console.WriteLine(timer.Elapsed.TotalSeconds); }
// =========== Ключевой фрагмент ============ public IGetDictionaryLong<string, int> InsertPortion(IEnumerable<string> s_flow) { HashSet<string> hs = new HashSet<string>(); foreach (string s in s_flow) hs.Add(s); //string[] ssa = hs.OrderBy(s => new HashedString() { Str = s }).ToArray(); // Надо сделать более экономно string[] ssa = hs.Select(s => new { s = s, hs = new HashedString() { Str = s } }) .OrderBy(pa => pa.hs) .Select(pa => pa.s).ToArray(); if (ssa.Length == 0) throw new Exception("name table empty"); //s_index_array.IndexCell.Close(); // cssequence.Close(); // Подготовим основную ячейку для работы if (System.IO.File.Exists(path + "tmp.pac")) System.IO.File.Delete(path + "tmp.pac"); //System.IO.File.Copy(s_index_array_path + ".pac", path + "tmp.pac"); // Это по общей логике, но если снаружи изменится, надо изменить и тут PType tp_s_index_seq = new PTypeSequence(new PTypeRecord( new NamedType("halfkey", new PType(PTypeEnumeration.integer)), new NamedType("offset", new PType(PTypeEnumeration.longinteger)))); PaCell source = new PaCell(tp_s_index_seq, path + "tmp.pac", false); source.Fill(new object[0]); foreach (var v in s_index_array.IndexCell.Root.ElementValues()) source.Root.AppendElement(v); source.Flush(); PaCell target = s_index_array.IndexCell; target.Clear(); target.Fill(new object[0]); int ssa_ind = 0; bool ssa_notempty = true; string ssa_current = ssa_notempty ? ssa[ssa_ind] : null; ssa_ind++; // Для накопления пар List<KeyValuePair<string, int>> accumulator = new List<KeyValuePair<string, int>>(ssa.Length); // Очередной (новый) код (индекс) int code_new = 0; if (!source.IsEmpty && source.Root.Count() > 0) { code_new = (int)source.Root.Count(); PaEntry tab_entry = table.Element(0); // не было проверки на наличие хотя бы одного элемента // Сканируем индексный массив, элементы являются парами {halfkey, offset} foreach (object[] val in source.Root.ElementValues()) { // Пропускаю элементы из нового потока, которые меньше текущего сканированного элемента int halfkey = (int)val[0]; string s = null; // Будет запрос если понадобится int cmp = 0; while (ssa_notempty) // && (cmp = ssa_current.CompareTo(s)) <= 0 { int hash_current = ssa_current.GetHashModifiedBernstein();//1;//ssa_current.GetHashCode(); cmp = hash_current.CompareTo(halfkey); if (cmp == 0) { // Дополнительное упрядочивание по строке if (s == null) { tab_entry.offset = (long)val[1]; s = (string)tab_entry.Field(1).Field(1).Get(); } cmp = ssa_current.CompareTo(s); } if (cmp < 0) { // добавляется новый код // добавляем код в таблицу long offset = table.TableCell.Root.AppendElement(new object[] { false, new object[] { code_new, ssa_current } }); // Автоматом добавляем начало строки в offsets offset_array.IndexCell.Root.AppendElement(offset); // добавляем строчку в строковый индекс target.Root.AppendElement(new object[] { hash_current, offset }); accumulator.Add(new KeyValuePair<string, int>(ssa_current, code_new)); code_new++; } else if (cmp == 0) { // используется существующий код tab_entry.offset = (long)val[1]; object[] ob = (object[])tab_entry.Get(); object[] rec = (object[])ob[1]; int code = (int)rec[0]; string key = (string)rec[1]; accumulator.Add(new KeyValuePair<string, int>(key, code)); } else // if (cmp > 0) break; // Нужно дойти до него на следующем элементе в следующем цикле if (ssa_ind < ssa.Length) ssa_current = ssa[ssa_ind++]; //ssa.ElementAt<string>(ssa_ind); else ssa_notempty = false; } target.Root.AppendElement(val); // переписывается тот же объект } } // В массиве ssa могут остаться элементы, их надо просто добавить if (ssa_notempty) { do { // добавляем код в таблицу long offset = table.TableCell.Root.AppendElement(new object[] { false, new object[] { code_new, ssa_current } }); // Автоматом добавляем начало строки в offsets offset_array.IndexCell.Root.AppendElement(offset); // добавляем строчку в строковый индекс target.Root.AppendElement(new object[] { ssa_current.GetHashModifiedBernstein(), offset });//ssa_current.GetHashCode() accumulator.Add(new KeyValuePair<string, int>(ssa_current, code_new)); code_new++; if (ssa_ind < ssa.Length) ssa_current = ssa[ssa_ind]; ssa_ind++; } while (ssa_ind <= ssa.Length); } table.TableCell.Flush(); offset_array.IndexCell.Flush(); target.Flush(); source.Close(); System.IO.File.Delete(path + "tmp.pac"); // Финальный аккорд: формирование и выдача словаря DictionaryLong<string, int> dic = new DictionaryLong<string, int>(s=>(ulong) s.GetHashCode(), (ulong) accumulator.Count); foreach (var keyValuePair in accumulator.Where(keyValuePair => !dic.ContainsKey(keyValuePair.Key))) { dic.Add(keyValuePair.Key, keyValuePair.Value); } return dic; }