/// <summary> /// Internal /// </summary> /// <param name="node"></param> void CopyInternals(DataAsTree node) { node.DBreezeTableName = this.DBreezeTableName; node.Transaction = this.Transaction; node.nt2Write = this.nt2Write; node.nt2Read = this.nt2Read; node.nt3Write = this.nt3Write; node.nt3Read = this.nt3Read; }
IEnumerable <DataAsTree> ReadOutNodes(DataAsTree node, DBreeze.Transactions.Transaction tran) { foreach (var tn in node.GetChildren(tran)) { yield return(tn); foreach (var inode in ReadOutNodes(tn, tran)) { yield return(inode); } } }
IEnumerable <DataAsTree> ReadOutNodes(DataAsTree node) { foreach (var tn in node.GetChildren()) { yield return(tn); foreach (var inode in ReadOutNodes(tn)) { yield return(inode); } } }
/// <summary> /// Internal /// </summary> /// <param name="node"></param> /// <param name="protocolVersion"></param> /// <returns></returns> byte[] SetupValueRowFromNode(DataAsTree node, byte protocolVersion) { byte[] val = null; if (String.IsNullOrEmpty(node.NodeName)) { throw new Exception("Node name can't be empty"); } byte[] name = node.NodeName.To_UTF8Bytes(); if (name.Length > 256) { throw new Exception("Node name can't be more then 256"); } /* * Protocol: * 1byte - protocol version (starting from 1) * ... * than due to the protocol description */ switch (protocolVersion) { case 1: //First protocol type /* * Protocol: * 1byte - protocol version (starting from 1) * 16bytes link to content (or 0) * 1byte - lenght of NodeName * Nbytes - Name */ val = new byte[] { protocolVersion }.ConcatMany ( (node.ContentRef != null) ? node.ContentRef : new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, new byte[] { (byte)name.Length }, name ); break; } return(val); }
/// <summary> /// Initializing Root Node /// </summary> /// <param name="DBreezeTableName">Real table name in DBreeze, that will hold the structure, must be synchronized with other tables in transaction</param> /// <param name="tran"></param> /// <param name="maximalInsertSpeed">will use DBreeze Technical_SetTable_OverwriteIsNotAllowed among transaction for DBreezeTableName</param> public DataAsTree(string DBreezeTableName, DBreeze.Transactions.Transaction tran, bool maximalInsertSpeed = false) { if (tran == null) throw new Exception("Transaction is null"); if (RootNode != null) throw new Exception("Can't be more then one root node, use other constructor"); //Setting up RootNode this.RootNode = this; this.Transaction = tran; this.maximalInsertSpeed = maximalInsertSpeed; this.DBreezeTableName = DBreezeTableName; this.NodeId = 0; this.ParentNodeId = 0; }
/// <summary> /// Internal /// </summary> /// <param name="row"></param> /// <returns></returns> DataAsTree SetupNodeFromRow(DBreeze.DataTypes.Row <byte[], byte[]> row) { DataAsTree node = null; byte[] val = row.Value; /* * Protocol: * 1byte - protocol version (starting from 1) * ... * than due to the protocol description */ node = new DataAsTree(); switch (val[0]) { case 1: //First protocol type /* * Protocol: * 1byte - protocol version (starting from 1) * 16bytes link to content (or 0) * 1byte - lenght of NodeName * Nbytes - Name */ if ((val[1] | val[2] | val[3] | val[4] | val[5] | val[6] | val[7] | val[8]) != 0) { //We got content node.ContentRef = val.Substring(1, 16); } node.NodeName = val.Substring(18, val[17]).UTF8_GetString(); break; } node.ParentNodeId = row.Key.Substring(0, 8).To_Int64_BigEndian(); node.NodeId = row.Key.Substring(8, 8).To_Int64_BigEndian(); CopyInternals(node); return(node); }
/// <summary> /// Initializing Root Node /// </summary> /// <param name="DBreezeTableName">Real table name in DBreeze, that will hold the structure, must be synchronized with other tables in transaction</param> /// <param name="tran"></param> /// <param name="maximalInsertSpeed">will use DBreeze Technical_SetTable_OverwriteIsNotAllowed among transaction for DBreezeTableName</param> public DataAsTree(string DBreezeTableName, DBreeze.Transactions.Transaction tran, bool maximalInsertSpeed = false) { if (tran == null) { throw new Exception("Transaction is null"); } if (RootNode != null) { throw new Exception("Can't be more then one root node, use other constructor"); } //Setting up RootNode this.RootNode = this; this.Transaction = tran; this.maximalInsertSpeed = maximalInsertSpeed; this.DBreezeTableName = DBreezeTableName; this.NodeId = 0; this.ParentNodeId = 0; }
IEnumerable<DataAsTree> ReadOutNodes(DataAsTree node) { foreach (var tn in node.GetChildren()) { yield return tn; foreach (var inode in ReadOutNodes(tn)) yield return inode; } }
/// <summary> /// Removes node /// </summary> /// <param name="node"></param> public void RemoveNode(DataAsTree node) { this.RemoveNode(node.ParentNodeId, node.NodeId); }
/// <summary> /// <para>Adding children to the node</para> /// Table, storing data structure, must be in tran.SynchronizeTables list. /// Then transaction must be Committed in the end by the programmer. /// </summary> /// <param name="node"></param> /// <returns>return node with setup parent id</returns> public DataAsTree AddNode(DataAsTree node) { CheckTransaction(); if (node == null) { throw new Exception("Nodes is not supplied"); } SetupWriteTables(); byte[] val = null; long maxId = this.RootNode.Transaction.Select <byte[], long>(this.RootNode.DBreezeTableName, new byte[] { 1 }).Value; bool skipToFillNameIndex = false; if (node.NodeId == 0) { //Insert node.ParentNodeId = this.NodeId; maxId++; node.NodeId = maxId; } else { //Update if (node.NodeId == node.ParentNodeId) { throw new Exception("node.NodeId can't be equal to node.ParentNodeId"); } var oldRow = this.RootNode.nt2Write.Select <byte[], byte[]>(node.ParentNodeId.To_8_bytes_array_BigEndian().Concat(node.NodeId.To_8_bytes_array_BigEndian())); if (oldRow.Exists) { var oldNode = SetupNodeFromRow(oldRow); if (!oldNode.NodeName.Equals(node.NodeName, StringComparison.OrdinalIgnoreCase)) { RemoveOldNodeFromNameIndex(oldNode.NodeName, node.ParentNodeId.To_8_bytes_array_BigEndian().Concat(node.NodeId.To_8_bytes_array_BigEndian())); } else { skipToFillNameIndex = true; } } else { if (maxId >= node.NodeId && maxId >= node.ParentNodeId) { //Such NodeId was probably deleted, and now wants to be reconnected. //We allow that } else { if (node.NodeId == node.ParentNodeId) { throw new Exception("Supplied node.NodeId or node.ParentNodeId don't exist"); } } } } //ParentNodeId(long),NodeId(long) byte[] key = node.ParentNodeId.To_8_bytes_array_BigEndian() .Concat(node.NodeId.To_8_bytes_array_BigEndian()); if (node.NodeContent != null) { node.ContentRef = this.RootNode.nt2Write.InsertDataBlock(node.ContentRef, node.NodeContent); } else { node.ContentRef = null; } val = SetupValueRowFromNode(node, 1); CopyInternals(node); this.RootNode.nt2Write.Insert <byte[], byte[]>(key, val); /*node.NodeName index support*/ if (!skipToFillNameIndex) { DBreeze.DataTypes.Row <string, byte[]> nodeNameIndexRow = null; byte[] btNodeNameIndex = null; nodeNameIndexRow = nt3Write.Select <string, byte[]>(node.NodeName.ToLower()); if (nodeNameIndexRow.Exists) { btNodeNameIndex = nodeNameIndexRow.Value.Concat(key); } else { btNodeNameIndex = key; } this.RootNode.nt3Write.Insert <string, byte[]>(node.NodeName.ToLower(), btNodeNameIndex); } /*-----------------------------*/ //Latest used Id this.RootNode.Transaction.Insert <byte[], long>(this.RootNode.DBreezeTableName, new byte[] { 1 }, maxId); return(node); }//eo func
/// <summary> /// <para>Adding children to the node</para> /// Table, storing data structure, must be in tran.SynchronizeTables list. /// Then transaction must be Committed in the end by the programmer. /// </summary> /// <param name="nodes">Nodes to add to current node</param> /// <param name="tran">Existing transaction. Table, storing data structure, must be in tran.SynchronizeTables list</param> /// <param name="maximalSpeed">set it to true to gain maximal saving speed</param> /// <returns>return node with setup parent id</returns> public DataAsTree AddNode(DataAsTree node) { CheckTransaction(); if (node == null) throw new Exception("Nodes is not supplied"); SetupWriteTables(); byte[] val = null; long maxId = this.RootNode.Transaction.Select<byte[], long>(this.RootNode.DBreezeTableName, new byte[] { 1 }).Value; bool skipToFillNameIndex = false; if (node.NodeId == 0) { //Insert node.ParentNodeId = this.NodeId; maxId++; node.NodeId = maxId; } else { //Update if (node.NodeId == node.ParentNodeId) throw new Exception("node.NodeId can't be equal to node.ParentNodeId"); var oldRow = this.RootNode.nt2Write.Select<byte[], byte[]>(node.ParentNodeId.To_8_bytes_array_BigEndian().Concat(node.NodeId.To_8_bytes_array_BigEndian())); if (oldRow.Exists) { var oldNode = SetupNodeFromRow(oldRow); if (!oldNode.NodeName.Equals(node.NodeName, StringComparison.OrdinalIgnoreCase)) RemoveOldNodeFromNameIndex(oldNode.NodeName, node.ParentNodeId.To_8_bytes_array_BigEndian().Concat(node.NodeId.To_8_bytes_array_BigEndian())); else skipToFillNameIndex = true; } else { if (maxId >= node.NodeId && maxId >= node.ParentNodeId) { //Such NodeId was probably deleted, and now wants to be reconnected. //We allow that } else { if (node.NodeId == node.ParentNodeId) throw new Exception("Supplied node.NodeId or node.ParentNodeId don't exist"); } } } //ParentNodeId(long),NodeId(long) byte[] key = node.ParentNodeId.To_8_bytes_array_BigEndian() .Concat(node.NodeId.To_8_bytes_array_BigEndian()); if (node.NodeContent != null) { node.ContentRef = this.RootNode.nt2Write.InsertDataBlock(node.ContentRef, node.NodeContent); } else node.ContentRef = null; val = SetupValueRowFromNode(node, 1); CopyInternals(node); this.RootNode.nt2Write.Insert<byte[], byte[]>(key, val); /*node.NodeName index support*/ if (!skipToFillNameIndex) { DBreeze.DataTypes.Row<string, byte[]> nodeNameIndexRow = null; byte[] btNodeNameIndex = null; nodeNameIndexRow = nt3Write.Select<string, byte[]>(node.NodeName.ToLower()); if (nodeNameIndexRow.Exists) btNodeNameIndex = nodeNameIndexRow.Value.Concat(key); else btNodeNameIndex = key; this.RootNode.nt3Write.Insert<string, byte[]>(node.NodeName.ToLower(), btNodeNameIndex); } /*-----------------------------*/ //Latest used Id this.RootNode.Transaction.Insert<byte[], long>(this.RootNode.DBreezeTableName, new byte[] { 1 }, maxId); return node; }
/// <summary> /// <para>Adding children to the node</para> /// Table, storing data structure, must be in tran.SynchronizeTables list. /// Then transaction must be Committed in the end by the programmer. /// </summary> /// <param name="nodes">Nodes to add to current node</param> /// <param name="tran">Existing transaction. Table, storing data structure, must be in tran.SynchronizeTables list</param> /// <param name="maximalSpeed">set it to true to gain maximal saving speed</param> /// <returns>return node with setup parent id</returns> public DataAsTree AddNode(DataAsTree node, DBreeze.Transactions.Transaction tran, bool maximalSpeed = false) { CheckTransaction(tran); if (node == null) { throw new Exception("Nodes is not supplied"); } SetupWriteTables(tran, maximalSpeed); byte[] val = null; long maxId = tran.Select <byte[], long>(this.DBreezeTableName, new byte[] { 1 }).Value; bool skipToFillNameIndex = false; if (node.NodeId == 0) { //Insert node.ParentNodeId = this.NodeId; maxId++; node.NodeId = maxId; } else { //Update var oldRow = nt2Write.Select <byte[], byte[]>(node.ParentNodeId.To_8_bytes_array_BigEndian().Concat(node.NodeId.To_8_bytes_array_BigEndian())); if (oldRow.Exists) { var oldNode = SetupNodeFromRow(oldRow); if (!oldNode.NodeName.Equals(node.NodeName, StringComparison.OrdinalIgnoreCase)) { RemoveOldNodeFromNameIndex(oldNode.NodeName, node.ParentNodeId.To_8_bytes_array_BigEndian().Concat(node.NodeId.To_8_bytes_array_BigEndian())); } else { skipToFillNameIndex = true; } } else { //Fake? We create new row node.ParentNodeId = this.NodeId; maxId++; node.NodeId = maxId; } } //ParentNodeId(long),NodeId(long) byte[] key = node.ParentNodeId.To_8_bytes_array_BigEndian() .Concat(node.NodeId.To_8_bytes_array_BigEndian()); if (node.NodeContent != null) { node.ContentRef = nt2Write.InsertDataBlock(node.ContentRef, node.NodeContent); } else { node.ContentRef = null; } val = SetupValueRowFromNode(node, 1); CopyInternals(node); nt2Write.Insert <byte[], byte[]>(key, val); /*node.NodeName index support*/ if (!skipToFillNameIndex) { DBreeze.DataTypes.Row <string, byte[]> nodeNameIndexRow = null; byte[] btNodeNameIndex = null; nodeNameIndexRow = nt3Write.Select <string, byte[]>(node.NodeName.ToLower()); if (nodeNameIndexRow.Exists) { btNodeNameIndex = nodeNameIndexRow.Value.Concat(key); } else { btNodeNameIndex = key; } nt3Write.Insert <string, byte[]>(node.NodeName.ToLower(), btNodeNameIndex); } /*-----------------------------*/ //Latest used Id tran.Insert <byte[], long>(this.DBreezeTableName, new byte[] { 1 }, maxId); return(node); }//eo func
/// <summary> /// Internal /// </summary> /// <param name="node"></param> /// <param name="protocolVersion"></param> /// <returns></returns> byte[] SetupValueRowFromNode(DataAsTree node, byte protocolVersion) { byte[] val = null; if (String.IsNullOrEmpty(node.NodeName)) throw new Exception("Node name can't be empty"); byte[] name = node.NodeName.To_UTF8Bytes(); if (name.Length > 256) throw new Exception("Node name can't be more then 256"); /* Protocol: 1byte - protocol version (starting from 1) ... than due to the protocol description */ switch (protocolVersion) { case 1: //First protocol type /* Protocol: 1byte - protocol version (starting from 1) 16bytes link to content (or 0) 1byte - lenght of NodeName Nbytes - Name */ val = new byte[] { protocolVersion }.ConcatMany ( (node.ContentRef != null) ? node.ContentRef : new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, new byte[] { (byte)name.Length }, name ); break; } return val; }
/// <summary> /// Internal /// </summary> /// <param name="row"></param> /// <returns></returns> DataAsTree SetupNodeFromRow(DBreeze.DataTypes.Row<byte[], byte[]> row) { DataAsTree node = null; byte[] val = row.Value; /* Protocol: 1byte - protocol version (starting from 1) ... than due to the protocol description */ node = new DataAsTree(); switch (val[0]) { case 1: //First protocol type /* Protocol: 1byte - protocol version (starting from 1) 16bytes link to content (or 0) 1byte - lenght of NodeName Nbytes - Name */ if ((val[1] | val[2] | val[3] | val[4] | val[5] | val[6] | val[7] | val[8]) != 0) { //We got content node.ContentRef = val.Substring(1, 16); } node.NodeName = System.Text.Encoding.UTF8.GetString(val.Substring(18, val[17])); break; } node.ParentNodeId = row.Key.Substring(0, 8).To_Int64_BigEndian(); node.NodeId = row.Key.Substring(8, 8).To_Int64_BigEndian(); CopyInternals(node); return node; }
/// <summary> /// Removes node /// </summary> /// <param name="node"></param> /// <param name="tran"></param> /// <param name="maximalSpeed"></param> public void RemoveNode(DataAsTree node, DBreeze.Transactions.Transaction tran, bool maximalSpeed = false) { this.RemoveNode(node.ParentNodeId, node.NodeId, tran, maximalSpeed); }
/// <summary> /// Internal /// </summary> /// <param name="node"></param> void CopyInternals(DataAsTree node) { node.RootNode = this.RootNode; //node.DBreezeTableName = this.DBreezeTableName; //node.Transaction = this.Transaction; //node.nt2Write = this.nt2Write; //node.nt2Read = this.nt2Read; //node.nt3Write = this.nt3Write; //node.nt3Read = this.nt3Read; }
/// <summary> /// Removes node /// </summary> /// <param name="node"></param> /// <param name="tran"></param> /// <param name="maximalSpeed"></param> public void RemoveNode(DataAsTree node) { this.RemoveNode(node.ParentNodeId, node.NodeId); }