public int H(PxEntry tree) { return((int)tree.Field(0).Get() == Int32.MinValue ? 0 : 1 + Math.Max(H(tree.Field(1)), H(tree.Field(2)))); }
public static int H(PxEntry tree) { return(tree.Tag() == 0 ? 0 : 1 + Math.Max(H(tree.UElementUnchecked(1).Field(1)), H(tree.UElementUnchecked(1).Field(2)))); }
public int H(PxEntry tree) { return(Equals(getKey(tree.Field(0).Get()), keyOfEmpty) ? 0 : 1 + Math.Max(H(tree.Field(1)), H(tree.Field(2)))); }
// =============== Методы доступа к данным ================== internal PxEntry GetEntryById(string id) { int e_hs = id.GetHashCode(); PxEntry found = GetEntryByHash(e_hs); return(found); }
public static BTree ToBTree(this PxEntry elementsEntry, string path, Func <object, PxEntry, int> elementsComparer, Func <object, object> keySelector, bool editable) { var newTree = new BTree(((PTypeSequence)elementsEntry.Typ).ElementType, elementsComparer, path, readOnly: false); newTree.Fill(elementsEntry, keySelector, editable); return(newTree); }
private PxEntry GetEntryByHash(int e_hs) { PxEntry found = graph_x.Root.BinarySearchFirst(element => { int v = (int)element.Field(0).Get(); return(v < e_hs ? -1 : (v == e_hs ? 0 : 1)); }); return(found); }
// =============== Методы доступа к данным ================== internal PxEntry GetEntryById(string id) { int e_hs = id.GetHashCode(); PxEntry found = PxEntry.BinarySearch(graph_x.Root, element => { int v = (int)element.Field(0).Get().Value; return(v < e_hs ? -1 : (v == e_hs ? 0 : 1)); }); return(found); }
private static void Write(PxCell xcell, FileStream fs) { xcell.Root.Set(new object[] { 99, new object[0] }); xcell.Root.Field(1).SetRepeat(fs.Length); PxEntry zel = xcell.Root.Field(1).Element(0); fs.Position = 0L; xcell.BasicStream.Position = zel.offset; fs.CopyTo(xcell.BasicStream); xcell.BasicStream.Flush(); }
/* * пригодится, когда дерево оооочень большое будет, так ое, что список переполнит оперативную память * private void ChangeBalanceSlowlyLongSequence(object element, PxEntry lastUnBalanceNode) * { * var nodeBalance = lastUnBalanceNode; * // foreach (bool isLeft in listEntries4Balance) * int com = 0; * while (nodeBalance.Tag() != 0 && (com=elementDepth(element, nodeBalance.UElementUnchecked(1).Field(0))) != 0) * { * var nodeEntry = nodeBalance.UElementUnchecked(1); * var balanceEntry = nodeEntry.Field(3); * if (com < 0) * { * balanceEntry.Set((int) balanceEntry.Get().Value + 1); * nodeBalance = nodeEntry.Field(1); * } * else * { * balanceEntry.Set((int) balanceEntry.Get().Value - 1); * nodeBalance = nodeEntry.Field(2); * } * } * } * */ /// <summary> /// балансирует дерево поворотом влево /// </summary> /// <param name="root">PxEntry балансируемой вершины с балансом=-2</param> /// <param name="entries">balance entries of path from prime node to added(excluded from entries), and them balaces</param> private static void FixWithRotateLeft(PxEntry root, List <KeyValuePair <PxEntry, int> > entries) { var rootEntry = root.UElementUnchecked(1); var r = rootEntry.Field(2); //Right; var rEntry = r.UElementUnchecked(1); var rl = rEntry.Field(1); //right of Left; var rBalance = entries[1].Value; if (rBalance == 1) { var rlEntry = rl.UElementUnchecked(1); rlEntry.Field(3).Set(0); //запоминаем RL var rlold = rl.GetHead(); int rlBalance = (entries.Count == 2 ? 0 : entries[2].Value); //Изменяем правую rl.SetHead(rlEntry.Field(2).GetHead()); entries[1].Key.Set(Math.Min(0, -rlBalance)); //запоминаем правую var oldR = r.GetHead(); //изменяем корневую r.SetHead(rlEntry.Field(1).GetHead()); entries[0].Key.Set(Math.Max(0, -rlBalance)); //запоминаем корневую var rootOld = root.GetHead(); //RL теперь корень root.SetHead(rlold); rootEntry = root.UElementUnchecked(1); //подставляем запомненые корень и правую. rootEntry.Field(1).SetHead(rootOld); rootEntry.Field(2).SetHead(oldR); return; } if (rBalance == -1) { entries[0].Key.Set(0); entries[1].Key.Set(0); } else //0 { entries[0].Key.Set(-1); entries[1].Key.Set(1); } var rOld = r.GetHead(); r.SetHead(rl.GetHead()); rl.SetHead(root.GetHead()); root.SetHead(rOld); }
/// <summary> /// Отображает грфик в EXEL, но не сохраняет его. /// </summary> /// <param name="xy">корневой массив-линий, листовой точек. Точки должны отличться на одну постоянноую величину</param> // static void Draw(int[][] xy) // { // Application application = new Application(){Visible = true}; // var workbooks = application.Workbooks; // var wordBook = workbooks.Open(new DirectoryInfo(Directory.GetCurrentDirectory()).Parent.Parent.FullName+"/chart.xls"); // var sheet = (_Worksheet) wordBook.ActiveSheet; //var chart =(_Chart)wordBook.Charts.Add(); // chart.Name = "sdfs"; // Thread.CurrentThread.CurrentCulture=new CultureInfo("en-US"); // sheet.ClearArrows(); // for (int j = 0; j < xy.Length; j++) // for (int i = 0; i < xy[0].Length; i++) // { // { // sheet.Cells[i + 1, j + 1] = xy[j][i].ToString(CultureInfo.InvariantCulture); // } // } // chart.ChartWizard(sheet.Range["A1", "G" + xy[0].Length], XlChartType.xlLine); // //System.Runtime.InteropServices.Marshal.ReleaseComObject(chart); // //System.Runtime.InteropServices.Marshal.ReleaseComObject(sheet); // //wordBook.Close(false); // //System.Runtime.InteropServices.Marshal.ReleaseComObject(wordBook); // //System.Runtime.InteropServices.Marshal.ReleaseComObject(workbooks); // //System.Runtime.InteropServices.Marshal.ReleaseComObject(application); // } private static void TestSearch(BTree cell, string name) { PxEntry found = cell.BinarySearch(pe => { string s = (string)pe.Field(0).Get(); return(String.Compare(name, s, StringComparison.Ordinal)); }); if (found.offset == long.MinValue) { Console.WriteLine("Имя {0} не найдено", name); } else { var res3 = found.GetValue(); Console.WriteLine(res3.Type.Interpret(res3.Value)); } }
private bool TryGetRecord(int code, out record rec) { if (codeRec.TryGetValue(code, out rec)) { return(true); } if (tofilldictionary) { return(false); } PxEntry entry = tree_fix.Root.BinarySearchFirst(en => ((int)en.Field(0).Get()).CompareTo(code)); if (entry.IsEmpty) { return(false); } rec = AddRecordToDictionary((object[])entry.Get()); return(true); }
/// <summary> /// балансирует дерево поворотом вправо /// </summary> /// <param name="root">PxEntry балансируемой вершины с балансом=2</param> /// <param name="entries"> пары: PxEntry содержащая баланс и баланс, соответсвующие пути от балансируемой вершины (включительно) до добавленой не включительно</param> private static void FixWithRotateRight(PxEntry root, List <KeyValuePair <PxEntry, int> > entries) { var rootEntry = root.UElementUnchecked(1); var l = rootEntry.Field(1); //Left; var lEntry = l.UElementUnchecked(1); var lr = lEntry.Field(2); //right of Left; var leftBalance = entries[1].Value; if (leftBalance == -1) { var lrEntry = lr.UElementUnchecked(1); var lrold = lr.GetHead(); int lrBalance = (entries.Count == 2 ? 0 : entries[2].Value); lr.SetHead(lrEntry.Field(1).GetHead()); entries[1].Key.Set(Math.Max(0, -lrBalance)); var oldR = l.GetHead(); l.SetHead(lrEntry.Field(2).GetHead()); entries[0].Key.Set(Math.Min(0, -lrBalance)); var rootOld = root.GetHead(); root.SetHead(lrold); rootEntry = root.UElementUnchecked(1); rootEntry.Field(2).SetHead(rootOld); rootEntry.Field(1).SetHead(oldR); rootEntry.Field(3).Set(0); return; } if (leftBalance == 1) // 1 { entries[0].Key.Set(0); entries[1].Key.Set(0); } else // 0 { entries[0].Key.Set(1); entries[1].Key.Set(-1); } var lOld = l.GetHead(); l.SetHead(lr.GetHead()); lr.SetHead(root.GetHead()); root.SetHead(lOld); }
public PxEntry BinarySearch(Func <PxEntry, int> eDepth) { var entry = Root; while (true) { if (entry.Tag() == 0) { return(new PxEntry(entry.Typ, Int64.MinValue, entry.fis)); } PxEntry elementEntry = entry.UElementUnchecked(1).Field(0); // Можно сэкономить на запоминании входа для uelement'а int level = eDepth(elementEntry); if (level == 0) { return(elementEntry); } entry = entry.UElementUnchecked(1).Field(level < 0 ? 1 : 2); } }
//private static object[] ToTreeObjectWithBalance(ToTreeObjectParams @params, ref int h) //{ // if (@params.Len == 0) return Empty; // h++; // if (@params.Len == 1) // return new object[] // { // 1, new[] // { // // запись // @params.Elements[@params.Beg], // значение // Empty, // Empty, // 0 // } // }; // int leftH = 0, rightH = 0, l = @params.Len; // @params.Len /= 2; // var left = ToTreeObjectWithBalance(@params, ref leftH); // @params.Beg += @params.Len + 1; // @params.Len = l - @params.Len - 1; // return new object[] // { // 1, new[] // { // // запись // @params.Elements[@params.Beg + @params.Len], // значение // left, // ToTreeObjectWithBalance(@params, ref rightH), // leftH - rightH // } // }; //} public PxEntry BinarySearch(int key) { var entry = Root; while (true) { //if (entry.Tag() == 0) return new PxEntry(entry.Typ, Int64.MinValue, entry.fis); PxEntry elementEntry = entry.Field(0); // Можно сэкономить на запоминании входа для uelement'а var o = (int)elementEntry.Get(); if (o == key) { return(elementEntry); } if (o == Int32.MinValue) { return(new PxEntry(entry.Typ, Int64.MinValue, entry.fis)); } entry = entry.Field(1).UElementUnchecked(1).Field(o < key ? 0 : 1); } }
/// <summary> /// Находит в графе определение сущности и извлекает из него минимальную информацию /// </summary> /// <param name="id"></param> /// <returns></returns> internal EntityInfo GetEntityInfoById(string id) { PxEntry found = GetEntryById(id); if (found.IsEmpty) { return(null); } EntityInfo einfo = new EntityInfo(id, found); // Анализируем прямые объектные ссылки // Нас пока интересует только предикат типа string predicate_id = sema2012m.ONames.rdftypestring; int hs_type = predicate_id.GetHashCode(); var direct_ent = found.Field(1); foreach (var p_rec in direct_ent.Elements()) { // Возьмем первый элемент и отфильтруем по несовпадению int h = (int)p_rec.Field(0).Get().Value; if (h != hs_type) { continue; } // Теперь надо пройтись по списку и посмотреть реальные триплеты foreach (var off_en in p_rec.Field(1).Elements()) { long off = (long)off_en.Get().Value; // Находим триплет any_triplet.offset = off; var tri_o = any_triplet.Get().Value; Triplet tri = Triplet.Create(tri_o); // Еще отбраковка if (tri is OProp && tri.s == id && tri.p == predicate_id) { einfo.type = ((OProp)tri).o; break; } } } return(einfo); }
private static bool Equals(PxEntry left, PxEntry right, Func <object, object, bool> elementsComparer) { int tag; if ((tag = left.Tag()) != right.Tag()) { return(false); } if (tag == 0) { return(true); } var r = right.UElement(); var l = right.UElement(); bool @equals = elementsComparer(r.Field(0).Get(), l.Field(0).Get()); // bool b = (int) r.Field(3).Get().Value == (int) l.Field(3).Get().Value; return(@equals // && b && Equals(r.Field(1), l.Field(1)) && Equals(r.Field(2), l.Field(2))); }
public PxEntry BinarySearch(Tkey key) { var entry = Root; while (true) { //if (entry.Tag() == 0) return new PxEntry(entry.Typ, Int64.MinValue, entry.fis); PxEntry elementEntry = entry.Field(0); // Можно сэкономить на запоминании входа для uelement'а var o = getKey(elementEntry.Get()); if (Equals(o, key)) { return(elementEntry); } if (Equals(o, keyOfEmpty)) { return(new PxEntry(entry.Typ, Int64.MinValue, entry.fis)); } entry = entry.Field(1).UElementUnchecked(1).Field(keyComparer(o, key) < 0 ? 0 : 1); } }
public long SelectFirst(string id) { PxEntry candidate = icell.Root.BinarySearchFirst(entry => ((string)entry.Field(0).Get()).CompareTo(id)); return((long)candidate.Field(1).Get()); }
public void Fill(PxEntry elementsEntry, Func <object, object> orderKeySelector, bool editable) { Fill(elementsEntry.Elements() .Select(oe => oe.Get()), orderKeySelector, editable); }
public void PxEntryInitTests() { var entry = new PxEntry(); Assert.NotNull(entry); }
/// <summary> /// Поместить элемент в дерево в соответствии со значением функции сравнения, /// вернуть ссылку на голову нового дерева /// </summary> /// <param name="element"></param> /// <returns>была ли изменена высота дерева</returns> public void Add(object element) { var node = Root; var lastUnBalanceNode = node; listEntries4Balance.Clear(); //int h = 0; Tkey key, keyAdd = getKey(element); object value; while (Equals(key = getKey((value = node.Field(0).Get())), keyOfEmpty)) { // h++; counter++; PxEntry balanceEntry = node.Field(3); var balance = (int)balanceEntry.Get(); int cmp = keyComparer(key, keyAdd); if (cmp == 0) { var left = node.Field(1).GetHead(); var right = node.Field(2).GetHead(); node.Set(new [] { element, Empty, Empty, balance }); node.Field(1).SetHead(left); node.Field(2).SetHead(right); return; } if (balance != 0) { lastUnBalanceNode = node; listEntries4Balance.Clear(); } var goLeft = cmp < 0; //TODO catch overflow memory listEntries4Balance.Add(new KeyValuePair <PxEntry, int>(balanceEntry, goLeft ? balance + 1 : balance - 1)); node = node.Field(goLeft ? 1 : 2); } // когда дерево пустое, организовать одиночное значение node.Set(new[] { element, new object[] { 0, null }, new object[] { 0, null }, 0 }); if (listEntries4Balance.Count == 0) { return; } for (int i = 0; i < listEntries4Balance.Count; i++) { listEntries4Balance[i].Key.Set(listEntries4Balance[i].Value); } // ChangeBalanceSlowlyLongSequence(element, lastUnBalanceNode); int b = listEntries4Balance[0].Value; if (b == 2) { FixWithRotateRight(lastUnBalanceNode, listEntries4Balance); } else if (b == -2) { FixWithRotateLeft(lastUnBalanceNode, listEntries4Balance); } // return true; }
public void Fill(PxEntry elementsEntry, bool editable) { Fill(elementsEntry.Elements() .Select(oe => oe.Get()), editable); }
/// <summary> /// Поместить элемент в дерево в соответствии со значением функции сравнения, /// вернуть ссылку на голову нового дерева /// </summary> /// <param name="element"></param> /// <returns>была ли изменена высота дерева</returns> public void Add(object element) { var node = Root; var lastUnBalanceNode = node; listEntries4Balance.Clear(); int h = 0; while (node.Tag() != 0) { h++; var nodeEntry = node.UElementUnchecked(1); counter++; int cmp = elementDepth(element, nodeEntry.Field(0)); PxEntry balanceEntry = nodeEntry.Field(3); var balance = (int)balanceEntry.Get(); if (cmp == 0) { var left = nodeEntry.Field(1).GetHead(); var right = nodeEntry.Field(2).GetHead(); node.Set(new object[] { 1, new[] { element, Empty, Empty, balance } }); node.UElementUnchecked(1).Field(1).SetHead(left); node.UElementUnchecked(1).Field(2).SetHead(right); return; } if (balance != 0) { lastUnBalanceNode = node; listEntries4Balance.Clear(); } var goLeft = cmp < 0; //TODO catch overflow memory listEntries4Balance.Add(new KeyValuePair <PxEntry, int>(balanceEntry, goLeft ? balance + 1 : balance - 1)); node = nodeEntry.Field(goLeft ? 1 : 2); } // когда дерево пустое, организовать одиночное значение node.Set(new object[] { 1, new[] { element, new object[] { 0, null }, new object[] { 0, null }, 0 } }); if (listEntries4Balance.Count == 0) { return; } for (int i = 0; i < listEntries4Balance.Count; i++) { listEntries4Balance[i].Key.Set(listEntries4Balance[i].Value); } // ChangeBalanceSlowlyLongSequence(element, lastUnBalanceNode); int b = listEntries4Balance[0].Value; if (b == 2) { FixWithRotateRight(lastUnBalanceNode, listEntries4Balance); } else if (b == -2) { FixWithRotateLeft(lastUnBalanceNode, listEntries4Balance); } // return true; }
public EntityInfo(string id, PxEntry entry) { this.id = id; this.entry = entry; }
static void Main(string[] args) { string path = @"..\..\..\Databases\"; InitTypes(); DateTime tt0 = DateTime.Now; // Проверка объекта object[] testdb = new object[] { new object[] { 1, new object[] { "a", "b", "c" } }, new object[] { 1, new object[] { "a1", "b1", "c1" } }, new object[] { 2, new object[] { "da", "db", "dc", "lang" } } }; Console.WriteLine(seqtriplets.Interpret(testdb)); // Создание ячейки плавающего формата string testpacfilename = path + "test.pac"; if (System.IO.File.Exists(testpacfilename)) { System.IO.File.Delete(testpacfilename); } PaCell cell = new PaCell(seqtriplets, testpacfilename, false); // false - чтобы заполнять // Заполнение ячейки данными из объекта cell.Fill(testdb); // Проверка того, что имеется в ячейке var cell_pvalue = cell.Root.GetValue(); Console.WriteLine(cell_pvalue.Type.Interpret(cell_pvalue.Value)); PTypeUnion tp_u = new PTypeUnion(); tp_u.Variants = new[] { new NamedType("empty", new PType(PTypeEnumeration.none)), new NamedType("node", new PTypeRecord( new NamedType("f0", new PType(PTypeEnumeration.boolean)), new NamedType("f1", new PTypeSequence(tp_u)))) }; object[] vv = new object[] { 1, new object[] { true, new object[] { new object[] { 1, new object[] { false, new object[0] } } } } }; PxCell xcell = new PxCell(tp_u, path + "xcell.pxc", false); xcell.Fill(vv); PxEntry e1 = xcell.Root.UElement().Field(1); PxEntry e2 = e1.Element(0); var v = e2.GetValue(); Console.WriteLine(v.Type.Interpret(v.Value)); return; //cell.Clear(); //cell.Fill(testtriplets); // проверка на то, что при неочищенной ячейке, записать в нее нельзя //cell.Close(); //cell.Clear(); //cell.Fill(testtriplets); // проверка на то, что при очищении, записать можно //// Проверка серийного буфера, в него загружаются данные из XML-файла, в ячейку ничего не помещается //// Этот тест, для начала, можно пропустить. //tt0 = DateTime.Now; //SerialBuffer buff = new SerialBuffer(new SerialFlowReceiverStub(seqtriplets)); //TestSerialInput(buff, path); //Console.WriteLine("Число элементов в объекте:" + ((object[])buff.Result).LongLength); //Console.WriteLine("Forming buffer ok. duration=" + (DateTime.Now - tt0).Ticks / 10000L); tt0 = DateTime.Now; // Проверка ввода из серийного скобочного потока для ячейки свободного формата // В данном случае, поток порождается при сканировании XML-документа tt0 = DateTime.Now; cell.Clear(); TestSerialInput(cell, path); Console.WriteLine("Число элементов в объекте:" + cell.Root.Count()); Console.WriteLine("Serial input ok. duration=" + (DateTime.Now - tt0).Ticks / 10000L); tt0 = DateTime.Now; cell.Close(); // Ячейка закрыта, теперь ее нельзя использовать // Проверка создания ячейки в режиме чтения PaCell cell2pac = new PaCell(seqtriplets, testpacfilename); long cnt2 = cell2pac.Root.Count(); var pval2 = cell2pac.Root.Element(100000).GetValue(); Console.WriteLine("cnt2=" + cnt2 + " Element(100000).Get()=" + pval2.Type.Interpret(pval2.Value)); Console.WriteLine("ReadObly cell ok. duration=" + (DateTime.Now - tt0).Ticks / 10000L); tt0 = DateTime.Now; // Создание ячейки фиксированного формата xcell.Clear(); xcell = new PxCell(seqtriplets, path + "test.pxc", false); var pv = cell2pac.Root.Get(); tt0 = DateTime.Now; xcell.Fill2(pv); // Плохой метод, заменю на хороший Console.WriteLine("xcell Fill ok. duration=" + (DateTime.Now - tt0).Ticks / 10000L); tt0 = DateTime.Now; // Проверка наполнения PxEntry rxt = xcell.Root; var ele = rxt.Element(400000).GetValue(); Console.WriteLine(ele.Type.Interpret(ele.Value)); Console.WriteLine("ok. duration=" + (DateTime.Now - tt0).Ticks / 10000L); tt0 = DateTime.Now; }