Ierarchical DataStructure. Any node can have subnodes and own binary content
예제 #1
0
 /// <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;
 }
예제 #2
0
        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);
                }
            }
        }
예제 #3
0
        IEnumerable <DataAsTree> ReadOutNodes(DataAsTree node)
        {
            foreach (var tn in node.GetChildren())
            {
                yield return(tn);

                foreach (var inode in ReadOutNodes(tn))
                {
                    yield return(inode);
                }
            }
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
        /// <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;
        }
예제 #6
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);
        }
예제 #7
0
        /// <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;
        }
예제 #8
0
 IEnumerable<DataAsTree> ReadOutNodes(DataAsTree node)
 {
     foreach (var tn in node.GetChildren())
     {
         yield return tn;
         foreach (var inode in ReadOutNodes(tn))
             yield return inode;
     }
 }
예제 #9
0
 /// <summary>
 ///  Removes node
 /// </summary>
 /// <param name="node"></param>
 public void RemoveNode(DataAsTree node)
 {
     this.RemoveNode(node.ParentNodeId, node.NodeId);
 }
예제 #10
0
        /// <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
예제 #11
0
        /// <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;
        }
예제 #12
0
        /// <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
예제 #13
0
        /// <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;
        }
예제 #14
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 = 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;
        }
예제 #15
0
 /// <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);
 }
예제 #16
0
 /// <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;
 }
예제 #17
0
 /// <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);
 }