public string Dump(DBNode root, int indent = 0) { var result = new String(' ', indent); result += root.Level + "_" + root.Index + " "; result += "[ "; foreach (var k in root.Keys) { result += k + ", "; } result = result.Substring(0, result.Length - 2) + " ]"; if (!root.HasChild) { result += " => [ " + root.ToString() + " ]"; } result += "\n"; foreach (var c in root.ChildNodes) { if (c != null) { result += Dump(c, indent + 1); } } return(result); }
public void SubExclude(DBNode root, int[] keys, int divLevel, object userData = null) { if (SubDividable(root, keys, divLevel)) { SubExclude_R(root, keys, divLevel, userData); } }
QueryResult Insert(DBNode root, int[] keys, int insertLevel, object userData = null) { if (root.Level < insertLevel) { return(null); } if (root.Level == insertLevel) //Insertion fail { return(new QueryResult(root, false)); //throw new DBInsertNodeExistException(); } int index = GetLevelIndex(keys, root.Level - 1); //Debug.Assert(rootLevel >= insertLevel); if (root.ChildNodes[index] == null) { //root.ChildNodes[index] = CreateNode(); if (root.Level == insertLevel + 1) { var node = CreateLeafNode(); node.SetParent(root, index); node.OnInsert(userData); return(new QueryResult(node, true)); } else { var node = CreateNode(); node.SetParent(root, index); } } return(Insert(root.ChildNodes[index], keys, insertLevel)); }
/// <summary> /// /// </summary> /// <param name="keys"></param> /// <param name="searchLevel"></param> /// <param name="root"></param> /// <returns></returns> public QueryResult Search(int[] keys, int searchLevel, DBNode root = null) { if (root == null) { root = Root; } if (this != root.Manager) { return(null); } CheckKeysSize(keys); if (root.Level < searchLevel) { return(null); } for (int i = 0; i < Dimension; i++) { if ((keys[i] >> root.Level) << root.Level != root.Keys[i]) { return(null); } } return(Search_r(keys, searchLevel, root)); }
//public virtual void OnSubDivision(int[][] childKeys, int childLevel, object userData) { } public DBNode(DBManager manager, int level = -1) { this.Manager = manager; this.ChildNodes = new DBNode[manager.DivisionCount]; Index = -1; Parent = null; Level = level; }
public void UnsetParent() { if (Parent != null && Index > 0 && Index < Manager.DivisionCount && Parent.ChildNodes[Index] == this) { Parent.ChildNodes[Index] = null; } Parent = null; Index = -1; }
public void SetParent(DBNode parent, int id) { if (parent != null && id >= 0 && id < Manager.DivisionCount) { Parent = parent; Parent.ChildNodes[id] = this; Index = id; Level = Parent.Level - 1; Keys = Manager.CalcChildKeys(parent.Keys, parent.Level, id); } }
public void SubDivide(DBNode root, int[] keys, int divLevel, object userData = null) { if (keys != null && SubDividable(root, keys, divLevel)) { SingleSubDivide_R(root, keys, divLevel, userData); } if (keys == null && SubDividable(root, root.Keys, divLevel)) { FullSubDivide(root, divLevel, userData); } }
public void DeleteTree(DBNode node /*, bool checkManager=true*/) { for (int i = 0; i < DivisionCount; i++) { if (node.ChildNodes[i] != null) { Delete(node.ChildNodes[i]); } } node.OnDelete(); node.UnsetParent(); }
//class DBTreeErrorException : Exception { } //class DBInsertNodeExistException : Exception { } public void Delete(DBNode node) { if (node.Manager != this || node.Parent == null || node.Parent.Manager != this) { return; } var endnode = node.Parent; DeleteTree(node); while (endnode != null && !endnode.HasChild) { var parent = endnode.Parent; endnode.UnsetParent(); endnode = parent; } }
void SubExclude_R(DBNode root, int[] keys, int divLevel, object userData) { int index = GetLevelIndex(keys, root.Level - 1); for (int i = 0; i < DivisionCount; i++) { if (index != i) { var node = CreateLeafNode(); node.SetParent(root, i); node.OnInsert(userData); } else if (root.Level > divLevel + 1) { var node = CreateNode(); node.SetParent(root, i); SubExclude_R(node, keys, divLevel, userData); } } }
void FullSubDivide(DBNode root, int divLevel, object userData) { if (root.Level > divLevel + 1) { for (int i = 0; i < DivisionCount; i++) { var node = CreateNode(); //node.OnInsert(keys, root.Level - 1, userData); node.SetParent(root, i); FullSubDivide(node, divLevel, userData); } } else { for (int i = 0; i < DivisionCount; i++) { var node = CreateLeafNode(); node.SetParent(root, i); node.OnInsert(userData); } } }
bool SubDividable(DBNode root, int[] keys, int divLevel) { if (root.Level <= divLevel) { return(false); } for (int i = 0; i < Dimension; i++) { if ((keys[i] >> root.Level) << root.Level != root.Keys[i]) { return(false); } } if (root.HasChild) { return(false); } return(true); }
/// <summary> /// /// </summary> /// <param name="keys"></param> /// <param name="searchLevel"></param> /// <param name="root"></param> /// <returns></returns> QueryResult Search_r(int[] keys, int searchLevel, DBNode root) { if (root.Level == searchLevel) { return(new QueryResult(root, true)); } int index = GetLevelIndex(keys, root.Level - 1); if (root.ChildNodes[index] == null) { return(new QueryResult(root, false)); } var result = Search_r(keys, searchLevel, root.ChildNodes[index]); if (result == null) { result = new QueryResult(root, false); } return(result); }
public QueryResult(DBNode result, bool match, string message = null) { Result = result; Succeed = match; Message = message; }