示例#1
0
        public void Add(int key, LTrieGenerationNode value)
        {
            if (key != size)
            {
                throw new Exception("LTrieAsciiGenerationMap Generation Map error Add Index");
            }

            ReGenerateMapUpToIndex = true;

            if ((_d.Length - 1) < key)
            {
                Array.Resize(ref _d, key * 2);
            }

            _d[key] = value;

            //LTrieGenerationNode node = null;
            //_d.TryGetValue(key, out node);
            //if (node == null)
            //    _d.Add(key, value);
            //else
            //    _d[key] = value;



            //Place is ok!
            size++;
        }
示例#2
0
        /// <summary>
        /// ItBwdFromTo
        /// </summary>
        /// <param name="gn"></param>
        /// <param name="generationMapLine"></param>
        /// <param name="useCache"></param>
        /// <returns></returns>
        private IEnumerable<LTrieRow> ItBwdFromTo(LTrieGenerationNode gn, byte[] generationMapLine, bool useCache)
        {
            byte[] key = null;
            LTrieRow row = null;
            long valueStartPtr = 0;
            uint valueLength = 0;
            byte[] xValue = null;

            byte[] gml = null;

            int startFrom = 0;
            if (keyIsFound)
            {
                startFrom = 255; //will check starting from KidsValue and then 0-255
            }
            else
            {
                //Kid is still not found
                if (generationMapLine.Length > initialKey.Length)
                {
                    startFrom = 256;
                }
                else
                {
                    startFrom = initialKey[generationMapLine.Length - 1];
                }
            }

            foreach (var kd in gn.KidsInNode.GetKidsBackward(startFrom))
            {

                if (kd.ValueKid || !kd.LinkToNode)
                {
                    //Value Kid

                    if (ReturnKeyValuePair)
                    {
                        this._root.Tree.Cache.ReadKeyValue(useCache, kd.Ptr, out valueStartPtr, out valueLength, out key, out xValue);
                    }
                    else
                    {
                        key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr);
                    }

                    if (keyIsFound)
                    {
                        //We return this one key

                        if ((includeStopKey) ? key.IfStringArrayBiggerOrEqualThen(endKey) : key.IfStringArrayBiggerThen(endKey))
                        {
                            row = new LTrieRow(this._root);

                            if (ReturnKeyValuePair)
                            {
                                row.ValueStartPointer = valueStartPtr;
                                row.ValueFullLength = valueLength;
                                row.Value = xValue;
                                row.ValueIsReadOut = true;
                            }
                            row.Key = key;
                            row.LinkToValue = kd.Ptr;
                            yield return row;
                        }
                        else
                        {
                            yield return null;
                            break;
                        }
                    }
                    else
                    {
                        //Checking if key equals to the found element, bigger or smaller

                        //Key is still not found

                        if ((includeStartKey) ? key.IfStringArraySmallerOrEqualThen(initialKey) : key.IfStringArraySmallerThen(initialKey))
                        {
                            keyIsFound = true;

                            if ((includeStopKey) ? key.IfStringArrayBiggerOrEqualThen(endKey) : key.IfStringArrayBiggerThen(endKey))
                            {
                                //We return this one key
                                row = new LTrieRow(this._root);
                                if (ReturnKeyValuePair)
                                {
                                    row.ValueStartPointer = valueStartPtr;
                                    row.ValueFullLength = valueLength;
                                    row.Value = xValue;
                                    row.ValueIsReadOut = true;
                                }
                                row.Key = key;
                                row.LinkToValue = kd.Ptr;
                                yield return row;
                            }
                            else
                            {
                                yield return null;
                                break;
                            }
                        }
                    }
                }
                else
                {
                    if (!keyIsFound && startFrom != 256 && startFrom > kd.Val)
                        keyIsFound = true;

                    //It's a Link To Node, gettign new generation Node
                    LTrieGenerationNode gn1 = new LTrieGenerationNode(this._root);
                    gn1.Pointer = kd.Ptr;
                    gn1.Value = (byte)kd.Val;
                    gml = generationMapLine.Concat(gn1.Value);
                    gn1.ReadSelf(useCache, gml);
                    //generationMapLine = generationMapLine.Concat(gn1.Value);
                    //gn1.ReadSelf(useCache, generationMapLine);

                    //foreach (var xr in ItBwdFromTo(gn1, generationMapLine, useCache))
                    foreach (var xr in ItBwdFromTo(gn1, gml, useCache))
                    {
                        if (xr == null)
                        {
                            yield return null;
                            break;
                        }
                        yield return xr;
                    }
                }
            }
        }
示例#3
0
        private IEnumerable<LTrieRow> ItBwdForMaximal(LTrieGenerationNode gn, byte[] generationMapLine, bool useCache)
        {
            byte[] key = null;
            LTrieRow row = null;
            long valueStartPtr = 0;
            uint valueLength = 0;
            byte[] xValue = null;
            byte[] gml = null;

            foreach (var kd in gn.KidsInNode.GetKidsBackward())
            {
                if (kd.ValueKid || !kd.LinkToNode)
                {
                    //Value Kid
                    //Raise Up Counter, iterate further if counter permits
                    //Console.WriteLine("KN: {0}", key.ToBytesString(""));

                    if (ReturnKeyValuePair)
                    {
                        this._root.Tree.Cache.ReadKeyValue(useCache, kd.Ptr, out valueStartPtr, out valueLength, out key, out xValue);
                    }
                    else
                    {
                        key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr);
                    }

                    row = new LTrieRow(this._root);

                    if (ReturnKeyValuePair)
                    {
                        row.ValueStartPointer = valueStartPtr;
                        row.ValueFullLength = valueLength;
                        row.Value = xValue;
                        row.ValueIsReadOut = true;
                    }
                    row.Key = key;
                    row.LinkToValue = kd.Ptr;
                    yield return row;
                }
                else
                {
                    //It's a Link To Node, gettign new generation Node
                    LTrieGenerationNode gn1 = new LTrieGenerationNode(this._root);
                    gn1.Pointer = kd.Ptr;
                    gn1.Value = (byte)kd.Val;
                    gml = generationMapLine.Concat(gn1.Value);
                    gn1.ReadSelf(useCache, gml);
                    //generationMapLine = generationMapLine.Concat(gn1.Value);
                    //gn1.ReadSelf(useCache, generationMapLine);

                    foreach (var xr in ItBwdForMaximal(gn1, gml, useCache))
                    //foreach (var xr in ItBwdForMaximal(gn1, generationMapLine, useCache))
                    {
                        yield return xr;
                    }
                }
            }
        }
示例#4
0
        public IEnumerable<LTrieRow> IterateBackwardStartsWith(byte[] initKey, bool useCache)
        {
            if (initKey.Length < 1)
                yield break;

            LTrieGenerationNode gn = null;

            initialKey = initKey;

            LTrieGenerationMap _generationMap = new LTrieGenerationMap();

            //_generationMap.Clear();

            //if (_generationMap.Count() == 0)
            //{
            //Loading it from Link TO ZERO Pointer
            gn = new LTrieGenerationNode(this._root);
            gn.Pointer = this._root.LinkToZeroNode;
            //gn.Value=0; - default
            _generationMap.Add(0, gn);

            gn.ReadSelf(useCache, _generationMap.GenerateMapNodesValuesUpToIndex(0));
            //}

            //ulong cnt = 0;

            byte[] generationMapLine = new byte[1] { 0 };
            byte[] gml = null;
            LTrieGenerationNode gn1 = null;
            byte[] key = null;
            LTrieRow row = null;

            //bool kFnd = false;

            foreach (var kd in gn.KidsInNode.GetKidsBackward(initialKey[0]))
            {
                //For first linke only
                if (kd.Val != initKey[0])
                    continue;

                //Kid can be value link or node link
                //if value link we can count 1 up
                if (kd.ValueKid || !kd.LinkToNode)
                {
                    key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr);
                    //Console.WriteLine("KN: {0}", key.ToBytesString(""));

                    if (key.IfStringArrayStartsWith(initialKey))
                    {

                        //cnt++;
                        row = new LTrieRow(this._root);
                        row.Key = key;
                        row.LinkToValue = kd.Ptr;
                        yield return row;

                    }
                }
                else
                {
                    gn1 = new LTrieGenerationNode(this._root);
                    gn1.Pointer = kd.Ptr;
                    gn1.Value = (byte)kd.Val;
                    gml = generationMapLine.Concat(gn1.Value);
                    gn1.ReadSelf(useCache, gml);
                    //generationMapLine = generationMapLine.Concat(gn1.Value);
                    //gn1.ReadSelf(useCache, generationMapLine);

                    //foreach (var xr in ItBwdStartsWith(gn1, generationMapLine, 1, true, useCache))
                    foreach (var xr in ItBwdStartsWith(gn1, gml, 1, useCache))
                    {
                        //cnt++;
                        yield return xr;
                    }
                }
            }

            //Console.WriteLine("CNT: {0}", cnt);
        }
示例#5
0
        public IEnumerable<LTrieRow> IterateBackwardStartFrom(byte[] initKey, bool inclStartKey, bool useCache)
        {
            LTrieGenerationNode gn = null;

            initialKey = initKey;
            includeStartKey = inclStartKey;

            LTrieGenerationMap _generationMap = new LTrieGenerationMap();

            //if (_generationMap.Count() == 0)
            //{
                //Loading it from Link TO ZERO Pointer
                gn = new LTrieGenerationNode(this._root);
                gn.Pointer = this._root.LinkToZeroNode;
                //gn.Value=0; - default
                _generationMap.Add(0, gn);

                gn.ReadSelf(useCache, _generationMap.GenerateMapNodesValuesUpToIndex(0));
            //}

            //ulong cnt = 0; //NEED ONLY FOR SKIP

            byte[] generationMapLine = new byte[1] { 0 };
            byte[] gml = null;
            LTrieGenerationNode gn1 = null;
            byte[] key = null;
            LTrieRow row = null;
            long valueStartPtr = 0;
            uint valueLength = 0;
            byte[] xValue = null;

            //Starting from first key. It's interesting inside of RecursiveYieldReturn to look Starting from value
            //If intialKey index already bigger then its own length
            //But for the first must be enough
            foreach (var kd in gn.KidsInNode.GetKidsBackward(initialKey[0]))
            {
                //Console.WriteLine("KN: {0}", key.ToBytesString(""));

                //Kid can be value link or node link
                //if value link we can count 1 up
                if (kd.ValueKid || !kd.LinkToNode)
                {

                    if (keyIsFound)
                    {
                        //We return this one key

                        //cnt++;
                        row = new LTrieRow(this._root);
                        if (ReturnKeyValuePair)
                        {
                            this._root.Tree.Cache.ReadKeyValue(useCache, kd.Ptr, out valueStartPtr, out valueLength, out key, out xValue);

                            row.ValueStartPointer = valueStartPtr;
                            row.ValueFullLength = valueLength;
                            row.Value = xValue;
                            row.ValueIsReadOut = true;
                        }
                        else
                        {
                            key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr);
                        }

                        row.Key = key;
                        row.LinkToValue = kd.Ptr;
                        yield return row;
                    }
                    else
                    {
                        if (ReturnKeyValuePair)
                        {
                            this._root.Tree.Cache.ReadKeyValue(useCache, kd.Ptr, out valueStartPtr, out valueLength, out key, out xValue);
                        }
                        else
                        {
                            key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr);
                        }
                        //Checking if key equals to the found element, bigger or smaller

                        //Key is still not found

                        if ((includeStartKey) ? key.IfStringArraySmallerOrEqualThen(initialKey) : key.IfStringArraySmallerThen(initialKey))
                        //if(key.IfStringArraySmallerThen(initialKey))
                        //if (IfFirstKeyIsSmallerThenCompareKey(key, initialKey))
                        {
                            keyIsFound = true;

                            //We return this one key
                            //We dont apply reading key with value here, using LazyLoading
                            //cnt++;
                            row = new LTrieRow(this._root);
                            if (ReturnKeyValuePair)
                            {
                                row.ValueStartPointer = valueStartPtr;
                                row.ValueFullLength = valueLength;
                                row.Value = xValue;
                                row.ValueIsReadOut = true;
                            }
                            row.Key = key;
                            row.LinkToValue = kd.Ptr;
                            yield return row;

                            //going on iteration
                        }
                    }
                }
                else
                {
                    if (!keyIsFound && initialKey[0] > kd.Val)
                        keyIsFound = true;

                    gn1 = new LTrieGenerationNode(this._root);
                    gn1.Pointer = kd.Ptr;
                    gn1.Value = (byte)kd.Val;
                    //increasing map line must hold already 2 elements
                    gml = generationMapLine.Concat(gn1.Value);
                    gn1.ReadSelf(useCache, gml);
                    //generationMapLine = generationMapLine.Concat(gn1.Value);
                    //gn1.ReadSelf(useCache, generationMapLine);

                    //foreach (var xr in ItBwdStartFrom(gn1, generationMapLine, useCache))
                    foreach (var xr in ItBwdStartFrom(gn1, gml, useCache))
                    {
                        //cnt++;      //NEED ONLY FOR SKIP
                        yield return xr;
                    }
                }
            }

            //Console.WriteLine("CNT: {0}", cnt);
        }
示例#6
0
        public IEnumerable<LTrieRow> IterateBackward(bool useCache)
        {
            LTrieGenerationNode gn = null;

            LTrieGenerationMap _generationMap = new LTrieGenerationMap();

            //_generationMap.Clear();

            //if (_generationMap.Count() == 0)
            //{
                //Loading it from Link TO ZERO Pointer
                gn = new LTrieGenerationNode(this._root);
                gn.Pointer = this._root.LinkToZeroNode;
                //gn.Value=0; - default
                _generationMap.Add(0, gn);

                gn.ReadSelf(useCache, _generationMap.GenerateMapNodesValuesUpToIndex(0));
            //}

            //ulong cnt = 0;

            byte[] generationMapLine = new byte[1] { 0 };
            byte[] gml = null;
            LTrieGenerationNode gn1 = null;
            byte[] key = null;
            LTrieRow row = null;
            long valueStartPtr = 0;
            uint valueLength = 0;
            byte[] xValue = null;

            foreach (var kd in gn.KidsInNode.GetKidsBackward())
            {
                //Kid can be value link or node link
                //if value link we can count 1 up
                if (kd.ValueKid || !kd.LinkToNode)
                {

                    //Console.WriteLine("KN: {0}", key.ToBytesString(""));

                    //cnt++;
                    row = new LTrieRow(this._root);

                    if (ReturnKeyValuePair)
                    {
                        this._root.Tree.Cache.ReadKeyValue(useCache, kd.Ptr, out valueStartPtr, out valueLength, out key, out xValue);

                        row.ValueStartPointer = valueStartPtr;
                        row.ValueFullLength = valueLength;
                        row.Value = xValue;
                        row.ValueIsReadOut = true;
                    }
                    else
                    {
                        key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr);
                    }

                    row.Key = key;
                    row.LinkToValue = kd.Ptr;
                    yield return row;
                }
                else
                {
                    gn1 = new LTrieGenerationNode(this._root);
                    gn1.Pointer = kd.Ptr;
                    gn1.Value = (byte)kd.Val;
                    gml = generationMapLine.Concat(gn1.Value);
                    gn1.ReadSelf(useCache, gml);
                    //generationMapLine = generationMapLine.Concat(gn1.Value);
                    //gn1.ReadSelf(useCache, generationMapLine);

                    //foreach (var xr in ItBwd(gn1, generationMapLine, useCache))
                    foreach (var xr in ItBwd(gn1, gml, useCache))
                    {
                        //cnt++;
                        yield return xr;
                    }
                }
            }

            //Console.WriteLine("CNT: {0}", cnt);
        }
示例#7
0
        private IEnumerable<LTrieRow> ItBwdStartsWith(LTrieGenerationNode gn, byte[] generationMapLine, int deep, bool useCache)
        {
            byte[] key = null;
            LTrieRow row = null;

            byte[] gml = null;
            long valueStartPtr = 0;
            uint valueLength = 0;
            byte[] xValue = null;

            foreach (var kd in gn.KidsInNode.GetKidsBackward())
            {

                //deep corresponds to search key(initialKey) index for compare value
                //deep can be bigger then initKey
                //in small deep kd.Value can represent link to node

                if (deep > (initialKey.Length-1))
                {
                    //we are bigger then supplied key for search (initialKey)
                    if (kd.ValueKid || !kd.LinkToNode)
                    {
                        //visualize all possible

                        if (ReturnKeyValuePair)
                        {
                            this._root.Tree.Cache.ReadKeyValue(useCache, kd.Ptr, out valueStartPtr, out valueLength, out key, out xValue);
                        }
                        else
                        {
                            key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr);
                        }

                        row = new LTrieRow(this._root);
                        row.Key = key;
                        if (ReturnKeyValuePair)
                        {
                            row.ValueStartPointer = valueStartPtr;
                            row.ValueFullLength = valueLength;
                            row.Value = xValue;
                            row.ValueIsReadOut = true;
                        }
                        row.LinkToValue = kd.Ptr;
                        yield return row;
                    }
                    else
                    {
                        //grow with ability to show all
                        LTrieGenerationNode gn1 = new LTrieGenerationNode(this._root);
                        gn1.Pointer = kd.Ptr;
                        gn1.Value = (byte)kd.Val;
                        gml = generationMapLine.Concat(gn1.Value);
                        gn1.ReadSelf(useCache, gml);

                        foreach (var xr in ItBwdStartsWith(gn1, gml, deep + 1,  useCache))
                        {
                            yield return xr;
                        }
                    }
                }
                else
                {
                    //search indexes still cooresponds to data

                    if (kd.Val == initialKey[deep]) //and we can compare every supplied byte with index
                    {
                        if (deep == (initialKey.Length - 1))
                        {
                            //final index length value
                            if (kd.ValueKid || !kd.LinkToNode)
                            {
                                //visualize

                                if (ReturnKeyValuePair)
                                {
                                    this._root.Tree.Cache.ReadKeyValue(useCache, kd.Ptr, out valueStartPtr, out valueLength, out key, out xValue);
                                }
                                else
                                {
                                    key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr);
                                }

                                row = new LTrieRow(this._root);
                                if (ReturnKeyValuePair)
                                {
                                    row.ValueStartPointer = valueStartPtr;
                                    row.ValueFullLength = valueLength;
                                    row.Value = xValue;
                                    row.ValueIsReadOut = true;
                                }
                                row.Key = key;
                                row.LinkToValue = kd.Ptr;
                                yield return row;
                            }
                            else
                            {
                                //grow with ability to show all
                                LTrieGenerationNode gn1 = new LTrieGenerationNode(this._root);
                                gn1.Pointer = kd.Ptr;
                                gn1.Value = (byte)kd.Val;
                                gml = generationMapLine.Concat(gn1.Value);
                                gn1.ReadSelf(useCache, gml);

                                foreach (var xr in ItBwdStartsWith(gn1, gml, deep + 1, useCache))
                                {
                                    yield return xr;
                                }
                            }
                        }
                        else
                        {
                            //smaller then final index length

                            if (kd.ValueKid || !kd.LinkToNode)
                            {
                                //do nothing in case of ValueKid
                                if (!kd.ValueKid)
                                {
                                    //Link to Value, probably this value suits to us
                                    key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr);

                                    if (key.IfStringArrayStartsWith(initialKey))
                                    {
                                        //visualize

                                        row = new LTrieRow(this._root);
                                        row.Key = key;
                                        row.LinkToValue = kd.Ptr;
                                        yield return row;
                                    }
                                }
                            }
                            else
                            {
                                //grow up
                                LTrieGenerationNode gn1 = new LTrieGenerationNode(this._root);
                                gn1.Pointer = kd.Ptr;
                                gn1.Value = (byte)kd.Val;
                                gml = generationMapLine.Concat(gn1.Value);
                                gn1.ReadSelf(useCache, gml);

                                foreach (var xr in ItBwdStartsWith(gn1, gml, deep + 1, useCache))
                                {
                                    yield return xr;
                                }
                            }
                        }

                    }
                    else
                    {
                        //do nothing
                    }
                }

            }
        }
示例#8
0
        //bool keyIsFound = false;
        private IEnumerable<LTrieRow> ItBwdSkipFrom(LTrieGenerationNode gn, byte[] generationMapLine, bool useCache)
        {
            byte[] key = null;
            LTrieRow row = null;
            byte[] gml = null;
            long valueStartPtr = 0;
            uint valueLength = 0;
            byte[] xValue = null;

            int startFrom = 0;
            if (keyIsFound)
            {
                startFrom = 255; //will check starting from KidsValue and then 0-255
            }
            else
            {
                //Kid is still not found
                if (generationMapLine.Length > initialKey.Length)
                {
                    startFrom = 256;
                }
                else
                {
                    startFrom = initialKey[generationMapLine.Length - 1];
                }
            }

            foreach (var kd in gn.KidsInNode.GetKidsBackward(startFrom))
            {
                if (kd.ValueKid || !kd.LinkToNode)
                {
                    //Value Kid

                    if (keyIsFound)
                    {
                        //We return this one key
                        skippedCnt++;

                        if (skippedCnt > skippingTotal)
                        {

                            if (ReturnKeyValuePair)
                            {
                                this._root.Tree.Cache.ReadKeyValue(useCache, kd.Ptr, out valueStartPtr, out valueLength, out key, out xValue);
                            }
                            else
                            {
                                key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr);
                            }

                            row = new LTrieRow(this._root);
                            if (ReturnKeyValuePair)
                            {
                                row.ValueStartPointer = valueStartPtr;
                                row.ValueFullLength = valueLength;
                                row.Value = xValue;
                                row.ValueIsReadOut = true;
                            }
                            row.Key = key;
                            row.LinkToValue = kd.Ptr;
                            yield return row;
                        }
                    }
                    else
                    {
                        key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr);

                        //Checking if key equals to the found element, bigger or smaller

                        //Key is still not found

                        if (key.IfStringArraySmallerOrEqualThen(initialKey))
                        //if (key.IfStringArraySmallerThen(initialKey))
                        //if (IfFirstKeyIsSmallerThenCompareKey(key, initialKey))
                        {
                            keyIsFound = true;

                            //case if Startkey doesn't exist, then first encountered value can be calculated as first for skipping
                            if (key.IfStringArraySmallerThen(initialKey))
                            {
                                skippedCnt++;

                                if (skippedCnt > skippingTotal)
                                {
                                   // key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr);

                                    row = new LTrieRow(this._root);
                                    row.Key = key;
                                    row.LinkToValue = kd.Ptr;
                                    yield return row;
                                }
                            }
                        }
                    }
                }
                else
                {
                    //It's a Link To Node, gettign new generation Node
                    LTrieGenerationNode gn1 = new LTrieGenerationNode(this._root);
                    gn1.Pointer = kd.Ptr;
                    gn1.Value = (byte)kd.Val;
                    gml = generationMapLine.Concat(gn1.Value);
                    gn1.ReadSelf(useCache, gml);
                    //generationMapLine = generationMapLine.Concat(gn1.Value);
                    //gn1.ReadSelf(useCache, generationMapLine);

                    //foreach (var xr in ItBwdSkipFrom(gn1, generationMapLine, useCache))
                    foreach (var xr in ItBwdSkipFrom(gn1, gml, useCache))
                    {
                        yield return xr;
                    }
                }
            }
        }
示例#9
0
        //#region "Checking Of Empty Pointer"

        ///// <summary>
        ///// Checks if pointer is empty
        ///// </summary>
        ///// <param name="ptr"></param>
        ///// <returns></returns>
        //public bool _IfPointerIsEmpty(byte[] ptr)
        //{
        //    //Executes 52 ms
        //    #region "Settign up delegate"
        //    switch (this.DefaultPointerLen)
        //    {
        //        case 5:     //Gives ability to allocate file up to 1 terrabyte (1.099.511.627.775)
        //            return !(
        //                   ptr[4] != 0
        //                   ||
        //                   ptr[3] != 0
        //                   ||
        //                   ptr[2] != 0
        //                   ||
        //                   ptr[1] != 0
        //                   ||
        //                   ptr[0] != 0
        //                   );
        //        case 4:     //4GB
        //             return !(
        //                   ptr[3] != 0
        //                   ||
        //                   ptr[2] != 0
        //                   ||
        //                   ptr[1] != 0
        //                   ||
        //                   ptr[0] != 0
        //                   );

        //        case 3:     //17MB
        //             return !(
        //                   ptr[2] != 0
        //                   ||
        //                   ptr[1] != 0
        //                   ||
        //                   ptr[0] != 0
        //                   );

        //        case 6:     //281 Terrabytes (281.474.976.710.655)
        //             return !(
        //                    ptr[5] != 0
        //                    ||
        //                    ptr[4] != 0
        //                    ||
        //                    ptr[3] != 0
        //                    ||
        //                    ptr[2] != 0
        //                    ||
        //                    ptr[1] != 0
        //                    ||
        //                    ptr[0] != 0
        //                    );

        //        case 7:     //72 Petabytes (72.057.594.037.927.935)
        //             return !(
        //                    ptr[6] != 0
        //                    ||
        //                    ptr[5] != 0
        //                    ||
        //                    ptr[4] != 0
        //                    ||
        //                    ptr[3] != 0
        //                    ||
        //                    ptr[2] != 0
        //                    ||
        //                    ptr[1] != 0
        //                    ||
        //                    ptr[0] != 0
        //                    );
        //        case 2:   //65 KB
        //             return !(
        //                   ptr[1] != 0
        //                   ||
        //                   ptr[0] != 0
        //                   );
        //        default:
        //            return ptr._ByteArrayEquals(this.EmptyPointer);

        //    }

        //    #endregion


        //}
        //#endregion



        #region "DATA FETCHING"



        /// <summary>
        ///
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public LTrieRow GetKey(byte[] key, bool useCache)
        {
            //Later change TreeKVP (for RootNode Interface or smth like this) and make it unversal, this one must return value
            LTrieRow kv = new LTrieRow(this);

            kv.Key = key;

            //if (key == null || key.Length == 0)
            //    return kv;

            if (key == null)
            {
                return(kv);
            }


            LTrieGenerationNode gn = null;

            if (_generationMap.Count() == 0)
            {
                //Loading it from Link TO ZERO Pointer
                gn         = new LTrieGenerationNode(this);
                gn.Pointer = this.LinkToZeroNode;
                //gn.Value=0; - default
                _generationMap.Add(0, gn);

                gn.ReadSelf(useCache, _generationMap.GenerateMapNodesValuesUpToIndex(0));
                //gn.ReadSelf();
            }

            bool cleanCheck = true;

            LTrieKid kidDef = null;
            int      p      = 0;

            int len = key.Length;


            /*SPECIAL CASE key = byte[0]*/
            if (key.Length == 0)
            {
                kidDef = _generationMap[0].GetKidAsValue(true, 1);
                if (kidDef.Exists)
                {
                    kv.LinkToValue = kidDef.Ptr;
                }
                return(kv);
            }
            /****************************/

            for (int i = 0; i < len; i++)
            {
                //Getting kid from actual generation map

                if (cleanCheck && i != 0 && _generationMap.ContainsKey(i) && _generationMap[i].Value != key[i - 1])
                {
                    cleanCheck = false;
                    _generationMap.RemoveBiggerOrEqualThenKey(i);
                }

                if (!_generationMap.ContainsKey(i))
                {
                    gn         = new LTrieGenerationNode(this);
                    gn.Value   = key[i - 1];
                    gn.Pointer = _generationMap[i - 1].KidsInNode.GetPointerToTheKid(key[i - 1]);

                    //FIND A SOLUTION FOR THIS NULL or EMPTY POINTER
                    //if (gn.Pointer == null || this._IfPointerIsEmpty(gn.Pointer))
                    //    return kv;
                    if (gn.Pointer == null || gn.Pointer._IfPointerIsEmpty(this.DefaultPointerLen))
                    {
                        return(kv);
                    }

                    _generationMap.Add(i, gn);

                    gn.ReadSelf(useCache, _generationMap.GenerateMapNodesValuesUpToIndex(i));
                    //gn.ReadSelf();
                }

                //Also if last element then supply 256 to get value not the link to value (if no value exit)
                //If kid is a link to next node we iterate further, if link on the value, we retrieve full key and value as link for TreeKVP stoping iteration
                //If link is empty (no kid) we return empty

                if (i >= key.Length)
                {
                    p = i - 1;
                }
                else
                {
                    p = i;
                }

                kidDef = _generationMap[i].GetKidAsValue((i >= (key.Length)), key[p]);

                if (kidDef.Exists)
                {
                    if (kidDef.ValueKid)
                    {
                        kv.LinkToValue = kidDef.Ptr;
                        return(kv);
                    }

                    if (!kidDef.LinkToNode)
                    {
                        //byte[] storedKey = _generationMap[i].ReadKidKeyFromValPtr(kidDef.Ptr);
                        long   valueStartPtr = 0;
                        uint   valueLength   = 0;
                        byte[] xValue        = null;
                        byte[] storedKey     = null;

                        if (!this.Tree.ValuesLazyLoadingIsOn)
                        {
                            this.Tree.Cache.ReadKeyValue(useCache, kidDef.Ptr, out valueStartPtr, out valueLength, out storedKey, out xValue);
                        }
                        else
                        {
                            storedKey = this.Tree.Cache.ReadKey(useCache, kidDef.Ptr);
                        }

                        // byte[] storedKey = this.Tree.Cache.ReadKey(useCache, kidDef.Ptr);

                        if (key.Length != storedKey.Length || !key._ByteArrayEquals(storedKey))
                        {
                            return(kv);
                        }

                        if (!this.Tree.ValuesLazyLoadingIsOn)
                        {
                            kv.ValueStartPointer = valueStartPtr;
                            kv.ValueFullLength   = valueLength;
                            kv.Value             = xValue;
                            kv.ValueIsReadOut    = true;
                        }
                        kv.LinkToValue = kidDef.Ptr;
                        return(kv);
                    }

                    if (i == key.Length - 1)
                    {
                        len++;
                    }

                    //iterating further
                }
                else
                {
                    return(kv);
                }
            }



            return(kv);
        }
示例#10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="WasUpdated">true means that value existed and was updated</param>
        /// <param name="dontUpdateIfExists">When true - if value exists, we dont update it. If WasUpdated = true then we value exists, if false - we have inserted new one</param>
        /// <returns></returns>
        public byte[] AddKey(ref byte[] key, ref byte[] value, out bool WasUpdated, bool dontUpdateIfExists)
        {
            //indicates that key we insert, already existed in the system and was updated
            WasUpdated = false;

            //if (key == null || key.Length == 0)
            //    return;
            if (key == null)
            {
                return(null);
            }

            if (key.Length > UInt16.MaxValue)
            {
                throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.KEY_IS_TOO_LONG);
            }



            LTrieGenerationNode gn = null;

            if (_generationMap.Count() == 0)
            {
                //Loading it from Link TO ZERO Pointer
                gn         = new LTrieGenerationNode(this);
                gn.Pointer = this.LinkToZeroNode;
                //gn.Value=0; - default
                _generationMap.Add(0, gn);

                gn.ReadSelf(false, null);
            }


            LTrieSetupKidResult res = new LTrieSetupKidResult();

            byte[] key1 = null; //we need it as null
            byte[] val1 = null;

            //len can be expanded inside of the algorithm maximum by one
            int len = key.Length;

            bool cleanCheck = true;



            /*Special case key is empty byte[0] */
            if (key.Length == 0)
            {
                //Saving byte[0] key
                res = _generationMap[0].SetupKidWithValue((byte)0, true, ref key, ref value, false, out WasUpdated, dontUpdateIfExists);

                return(res.ValueLink);
            }
            /**/


            for (int i = 0; i < len; i++)
            {
                //Getting kid from actual generation map

                if (cleanCheck && i != 0 && _generationMap.ContainsKey(i) && _generationMap[i].Value != key[i - 1])
                {
                    cleanCheck = false;

                    //In case if i>0, it's not the first element and we have to compare if there are generation mapsstarting from this point.
                    //If generationMap[i] exists and it's value not that what we want, we have to clean full in memory generation map as

                    //Save_node... up to i
                    Save_GM_nodes_Starting_From(i);

                    //Remove Gen Map starting from... i
                    _generationMap.RemoveBiggerOrEqualThenKey(i);
                }

                if (!_generationMap.ContainsKey(i))
                {
                    //All ok, for the first generation node

                    //We read or create generation map
                    //And add it to the _generationMap

                    gn         = new LTrieGenerationNode(this);
                    gn.Value   = key[i - 1];
                    gn.Pointer = _generationMap[i - 1].KidsInNode.GetPointerToTheKid(key[i - 1]);
                    //gn.Pointer = _generationMap[i - 1].GetKidPointer(key[i - 1]);

                    _generationMap.Add(i, gn);

                    if (gn.Pointer != null)
                    {
                        gn.ReadSelf(false, null);
                    }
                    else
                    {
                        gn.Pointer = new byte[DefaultPointerLen];       //!!!!!!!!!!!!! Check if it'S really necessary or we can leave it as null
                    }
                }


                //Generation Node in this trie can have link to kids [0-255] and link to the value.
                //If Kids>0 && Value Link is not Default Empty Pointer, then this value-link refers to the end of the sentence.
                //If Kids==0 && Value Link is not Default Empty Pointer, then this value-link refers to the sentence which can go after this last character, so also to the value.
                //Dual behaviour.


                if (res.KeyOldKid != null)
                {
                    //It means that on this stage probably we have to setup both kids
                    //We can check Length of both keys and their current condition

                    //key1 = res.KeyOldKid; //we need it as null
                    val1 = res.ValPtrOldKid;


                    if ((res.KeyOldKid.Length - 1) < i)
                    {
                        _generationMap[i].SetupKidWithValue((byte)0, true, ref key1, ref val1, true, out WasUpdated, dontUpdateIfExists);
                    }
                    else
                    {
                        _generationMap[i].SetupKidWithValue(res.KeyOldKid[i], false, ref key1, ref val1, true, out WasUpdated, dontUpdateIfExists);
                    }

                    //Cleaning up KeyOldKid - probably not necessary, de bene esse (just in case)
                    res.KeyOldKid = null;
                }


                //One more only then we setup value, otherwise we bind to the kid, Check Docs in fileDb LtrieSpreadExample1.jpg
                res = _generationMap[i].SetupKidWithValue(((i == key.Length) ? (byte)0 : key[i]), (i == key.Length), ref key, ref value, false, out WasUpdated, dontUpdateIfExists);

                if (!res.IterateFurther)
                {
                    //After setting up value, we can just exit
                    return(res.ValueLink);
                }
                else
                {
                    //we don't need value on this phase, we can go on further

                    //Expanding iteration cycle by one and, on the next iteration cycle we should go out from the loop.
                    if (i == (key.Length - 1))
                    {
                        len++;
                    }
                }
            }

            //Should not happen as null, we have to return link to the full value
            return(null);
        }

        /// <summary>
        /// Returns link to the full value together with the key
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="startIndex"></param>
        /// <param name="WasUpdated">indicates that key we insert, already existed in the system and was updated</param>
        /// <returns></returns>
        public byte[] AddKeyPartially(ref byte[] key, ref byte[] value, uint startIndex, out long valueStartPtr, out bool WasUpdated)
        {
            WasUpdated = false;

            if (key == null)
            {
                valueStartPtr = -1;
                return(null);
            }

            if (key.Length > UInt16.MaxValue)
            {
                throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.KEY_IS_TOO_LONG);
            }

            if (value == null)
            {
                throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.PARTIAL_VALUE_CANT_BE_NULL);
            }


            LTrieGenerationNode gn = null;

            if (_generationMap.Count() == 0)
            {
                //Loading it from Link TO ZERO Pointer
                gn         = new LTrieGenerationNode(this);
                gn.Pointer = this.LinkToZeroNode;
                //gn.Value=0; - default
                _generationMap.Add(0, gn);

                gn.ReadSelf(false, null);
            }


            LTrieSetupKidResult res = new LTrieSetupKidResult();

            byte[] key1 = null; //we need it as null
            byte[] val1 = null;

            //len can be expanded inside of the algorithm maximum by one
            int len = key.Length;

            bool cleanCheck = true;

            /*Special case key is empty byte[0] */
            if (key.Length == 0)
            {
                //Saving byte[0] key
                res = _generationMap[0].SetupKidWithValuePartially((byte)0, true, ref key, ref value, false, startIndex, out valueStartPtr, out WasUpdated);

                return(res.ValueLink);
            }
            /**/

            for (int i = 0; i < len; i++)
            {
                //Getting kid from actual generation map

                if (cleanCheck && i != 0 && _generationMap.ContainsKey(i) && _generationMap[i].Value != key[i - 1])
                {
                    cleanCheck = false;

                    //In case if i>0, it's not the first element and we have to compare if there are generation mapsstarting from this point.
                    //If generationMap[i] exists and it's value not that what we want, we have to clean full in memory generation map as

                    //Save_node... up to i
                    Save_GM_nodes_Starting_From(i);

                    //Remove Gen Map starting from... i
                    _generationMap.RemoveBiggerOrEqualThenKey(i);
                }

                if (!_generationMap.ContainsKey(i))
                {
                    //All ok, for the first generation node

                    //We read or create generation map
                    //And add it to the _generationMap

                    gn         = new LTrieGenerationNode(this);
                    gn.Value   = key[i - 1];
                    gn.Pointer = _generationMap[i - 1].KidsInNode.GetPointerToTheKid(key[i - 1]);
                    //gn.Pointer = _generationMap[i - 1].GetKidPointer(key[i - 1]);

                    _generationMap.Add(i, gn);

                    if (gn.Pointer != null)
                    {
                        gn.ReadSelf(false, null);
                    }
                    else
                    {
                        gn.Pointer = new byte[DefaultPointerLen];       //!!!!!!!!!!!!! Check if it'S really necessary or we can leave it as null
                    }
                }


                //Generation Node in this trie can have link to kids [0-255] and link to the value.
                //If Kids>0 && Value Link is not Default Empty Pointer, then this value-link refers to the end of the sentence.
                //If Kids==0 && Value Link is not Default Empty Pointer, then this value-link refers to the sentence which can go after this last character, so also to the value.
                //Dual behaviour.


                if (res.KeyOldKid != null)
                {
                    //It means that on this stage probably we have to setup both kids
                    //We can check Length of both keys and their current condition

                    //key1 = res.KeyOldKid; //we need it as null
                    val1 = res.ValPtrOldKid;


                    if ((res.KeyOldKid.Length - 1) < i)
                    {
                        _generationMap[i].SetupKidWithValuePartially((byte)0, true, ref key1, ref val1, true, startIndex, out valueStartPtr, out WasUpdated);
                    }
                    else
                    {
                        _generationMap[i].SetupKidWithValuePartially(res.KeyOldKid[i], false, ref key1, ref val1, true, startIndex, out valueStartPtr, out WasUpdated);
                    }

                    //Cleaning up KeyOldKid - probably not necessary, de bene esse (just in case)
                    res.KeyOldKid = null;
                }


                //One more only then we setup value, otherwise we bind to the kid, Check Docs in fileDb LtrieSpreadExample1.jpg
                res = _generationMap[i].SetupKidWithValuePartially(((i == key.Length) ? (byte)0 : key[i]), (i == key.Length), ref key, ref value, false, startIndex, out valueStartPtr, out WasUpdated);

                if (!res.IterateFurther)
                {
                    //After setting up value, we can just exit
                    return(res.ValueLink);
                }
                else
                {
                    //we don't need value on this phase, we can go on further

                    //Expanding iteration cycle by one and, on the next iteration cycle we should go out from the loop.
                    if (i == (key.Length - 1))
                    {
                        len++;
                    }
                }
            }

            //Should not happen as null, we have to return link to the full value
            valueStartPtr = -1;
            return(null);
        }

        /// <summary>
        /// Check TransactionCommit in case of RemoveAll with file Recreation.
        /// Note if some other threads are reading parallel data, exception will be thrown in their transaction.
        /// It's correct.
        /// </summary>
        /// <param name="withFileRecreation"></param>
        public void RemoveAll(bool withFileRecreation)
        {
            if (!withFileRecreation)
            {
                LTrieGenerationNode gn = null;

                _generationMap.Clear();

                if (_generationMap.Count() == 0)
                {
                    //Loading it from Link TO ZERO Pointer
                    gn         = new LTrieGenerationNode(this);
                    gn.Pointer = this.LinkToZeroNode;
                    //gn.Value=0; - default
                    _generationMap.Add(0, gn);

                    gn.ReadSelf(false, null);
                }


                _generationMap[0].RemoveAllKids();
            }
            else
            {
                try
                {
                    this.Tree.Cache.RecreateDB();

                    //Important, Better to re-read all generation nodes for safety reasons, de bene esse
                    this._generationMap.Clear();

                    //And re-Read RootNode
                    ReadRootNode();
                }
                catch (Exception ex)
                {
                    ////////////////////  MADE THAT Table is not Opearable on the upper level,
                    throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.RECREATE_TABLE_FAILED, this.Tree.TableName, ex);
                }
            }
        }

        /// <summary>
        /// Takes value fresh no committed value row.GetFullValue(false);
        /// </summary>
        /// <param name="oldKey"></param>
        /// <param name="newKey"></param>
        /// <returns></returns>
        public bool ChangeKey(ref byte[] oldKey, ref byte[] newKey)
        {
            byte[] refToInsertedValue = null;
            return(this.ChangeKey(ref oldKey, ref newKey, out refToInsertedValue));
        }

        /// <summary>
        /// Takes value fresh no committed value row.GetFullValue(false);
        /// </summary>
        /// <param name="oldKey"></param>
        /// <param name="newKey"></param>
        /// <param name="refToInsertedValue">returns ptr in the file to the new key</param>
        /// <returns></returns>
        public bool ChangeKey(ref byte[] oldKey, ref byte[] newKey, out byte[] refToInsertedValue)
        {
            //The best way read old, remove, and create new, with holding of transactions,
            //just changing pointers to the value will give nothing, because in the value also the full key is written, so we will need
            //to make new value
            refToInsertedValue = null;

            var row = this.GetKey(oldKey, false);

            if (row.Exists)
            {
                byte[] oldKeyValue  = row.GetFullValue(false);
                bool   WasRemoved   = false;
                byte[] deletedValue = null;
                this.RemoveKey(ref oldKey, out WasRemoved, false, out deletedValue);
                bool WasUpdated = false;
                refToInsertedValue = this.AddKey(ref newKey, ref oldKeyValue, out WasUpdated, false);

                refToInsertedValue = refToInsertedValue.EnlargeByteArray_BigEndian(8);

                return(true);
            }
            return(false);
        }

        /// <summary>
        /// Will return pointer to the value of the removing kid (if it existed). Otherwise NULL.
        /// </summary>
        /// <param name="key"></param>
        /// <param name="WasRemoved">indicates that value existed if true</param>
        /// <param name="retrieveDeletedValue">indicates if we should bind deleted value to the result</param>
        /// <param name="deletedValue">interesting only if WasRemoved = true and retrieveDeletedValue is true</param>
        /// <returns></returns>
        public void RemoveKey(ref byte[] key, out bool WasRemoved, bool retrieveDeletedValue, out byte[] deletedValue)
        {
            WasRemoved   = false;
            deletedValue = null;
            //if (key == null || key.Length == 0)
            //    return;

            if (key == null)
            {
                return;
            }

            if (key.Length > UInt16.MaxValue)
            {
                throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.KEY_IS_TOO_LONG);
            }


            LTrieGenerationNode gn = null;

            if (_generationMap.Count() == 0)
            {
                //Loading it from Link TO ZERO Pointer
                gn         = new LTrieGenerationNode(this);
                gn.Pointer = this.LinkToZeroNode;
                //gn.Value=0; - default
                _generationMap.Add(0, gn);

                gn.ReadSelf(false, null);
            }


            LTrieSetupKidResult res = new LTrieSetupKidResult();

            //byte[] key1 = null; //we need it as null
            //byte[] val1 = null;

            //len can be expanded inside of the algorithm maximum by one
            int len = key.Length;

            bool cleanCheck = true;

            bool iterateFurther = false;

            /*SPECIAL CASE key=byte[0]*/
            if (key.Length == 0)
            {
                _generationMap[0].RemoveKid((byte)0, true, ref key, out WasRemoved, retrieveDeletedValue, out deletedValue);

                return;
            }
            /***************************/

            for (int i = 0; i < len; i++)
            {
                //Getting kid from actual generation map

                if (cleanCheck && i != 0 && _generationMap.ContainsKey(i) && _generationMap[i].Value != key[i - 1])
                {
                    cleanCheck = false;

                    //In case if i>0, it's not the first element and we have to compare if there are generation mapsstarting from this point.
                    //If generationMap[i] exists and it's value not that what we want, we have to clean full in memory generation map as

                    //Save_node... up to i
                    Save_GM_nodes_Starting_From(i);

                    //Remove Gen Map starting from... i
                    _generationMap.RemoveBiggerOrEqualThenKey(i);
                }

                if (!_generationMap.ContainsKey(i))
                {
                    //All ok, for the first generation node

                    //We read or create generation map
                    //And add it to the _generationMap

                    gn         = new LTrieGenerationNode(this);
                    gn.Value   = key[i - 1];
                    gn.Pointer = _generationMap[i - 1].KidsInNode.GetPointerToTheKid(key[i - 1]);
                    //gn.Pointer = _generationMap[i - 1].GetKidPointer(key[i - 1]);

                    _generationMap.Add(i, gn);

                    if (gn.Pointer != null)
                    {
                        gn.ReadSelf(false, null);
                    }
                    else
                    {
                        gn.Pointer = new byte[DefaultPointerLen];       //!!!!!!!!!!!!! Check if it'S really necessary or we can leave it as null
                    }
                }

                //Trying to remove as a result we receive information if we should iterate further
                iterateFurther = _generationMap[i].RemoveKid((i == key.Length) ? (byte)0 : key[i], (i == key.Length), ref key, out WasRemoved, retrieveDeletedValue, out deletedValue);

                if (!iterateFurther)
                {
                    break;
                }
                else
                {
                    if (i == (key.Length - 1))
                    {
                        len++;
                    }
                }
            }
        }
示例#11
0
        public void Save_GM_nodes_Starting_From(int index)
        {
            //if (_generationMap.Count() == 0)
            //    return;

            //Going from last record to the first (last always has in kids references to values)
            //Saving one node after another, if node has grown up and will recide totally new place
            //in the file, then parent also has to be updated then gn.ParentChange flag will be true.

            bool ChangeParent            = false;
            LTrieGenerationNode prevNode = null;


            int gmMaxIndex = _generationMap.Count() - 1;

            foreach (var gn in _generationMap.Descending)
            {
                if (ChangeParent)
                {
                    //prev Node can't be null here

                    if (prevNode.ToRemoveFromParentNode)
                    {
                        gn.Value.RemoveKidPointer(prevNode.Value);
                    }
                    else
                    {
                        gn.Value.SetupKidPointer(prevNode.Value, prevNode.Pointer);
                    }

                    //Important switches
                    ChangeParent = false;
                    prevNode.ToChangeParentNode     = false;
                    prevNode.ToRemoveFromParentNode = false;
                }

                if (gn.Key < index)
                {
                    break;
                }


                //TESTS
                //Every element which must be save we try to represent as set of GN bytes starting from 0 up to this generation node
                //and record them as Key into memory dictionary with value byte[] oldKids, later reader will be able on every iteration point to request these kids from memory
                //Probably except 0 node, because for reading it will be not interesting, there LinkZeroNode is always synchronized


                //Adding MapKids and WritinSelf synchro is checked

                if (gmMaxIndex > 0)
                {
                    this.Tree.Cache.AddMapKids(_generationMap.GenerateMapNodesValuesUpToIndex(gmMaxIndex--), gn.Value.KidsBeforeModification);
                }

                //Writing on disk
                gn.Value.WriteSelf();


                if (gn.Key == 0)
                {
                    //Setting new LinkToZeroNode for Writing in into the ROOT

                    this.LinkToZeroNode = gn.Value.Pointer;

                    //Console.WriteLine("SAVING KEY: {0}", visualizeGenerationMap());
                }

                //Setting up vital variables
                prevNode     = gn.Value;
                ChangeParent = gn.Value.ToChangeParentNode;
            }
        }
示例#12
0
        public void IterateForwardStartsWith_Prefix_Helper(byte[] initKey, bool useCache)
        {
            LTrieGenerationNode gn = null;

            initialKey = initKey;

            LTrieGenerationMap _generationMap = new LTrieGenerationMap();

            //Loading it from Link TO ZERO Pointer
            gn = new LTrieGenerationNode(this._root);
            gn.Pointer = this._root.LinkToZeroNode;
            _generationMap.Add(0, gn);
            gn.ReadSelf(useCache, _generationMap.GenerateMapNodesValuesUpToIndex(0));

            byte[] generationMapLine = new byte[1] { 0 };
            byte[] gml = null;
            LTrieGenerationNode gn1 = null;
            byte[] key = null;
            LTrieRow row = null;

            //Starting from first key. It's interesting inside of RecursiveYieldReturn to look Starting from value
            //If intialKey index already bigger then its own length
            //But for the first must be enough
            foreach (var kd in gn.KidsInNode.GetKidsForward(initialKey[0]))
            {
                if (kd.Val != initKey[0])
                    continue;

                //Console.WriteLine(System.Text.Encoding.ASCII.GetString(new byte[] {initKey[0]}));

                //Kid can be value link or node link
                //if value link we can count 1 up
                if (kd.ValueKid || !kd.LinkToNode)
                {
                    PrefixDeep++;
                    //key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr);

                    //if (key[0] == initialKey[0])
                    //    lstClosestPrefix.Add(initialKey[0]);
                }
                else
                {
                    gn1 = new LTrieGenerationNode(this._root);
                    gn1.Pointer = kd.Ptr;
                    gn1.Value = (byte)kd.Val;
                    //increasing map line must hold already 2 elements
                    gml = generationMapLine.Concat(gn1.Value);
                    gn1.ReadSelf(useCache, gml);

                    PrefixDeep++;

                    foreach (var xr in ItFrwStartsWith_Prefix_Helper(gn1, gml, 1, useCache))
                    {
                        //we must iterate to fill lstClosestPrefix
                    }
                }
            }
        }
示例#13
0
        public IEnumerable<LTrieRow> IterateForwardStartsWith(byte[] initKey, bool useCache)
        {
            if (initKey.Length < 1)
                yield break;

            LTrieGenerationNode gn = null;

            initialKey = initKey;

            LTrieGenerationMap _generationMap = new LTrieGenerationMap();

            //if (_generationMap.Count() == 0)
            //{
            //Loading it from Link TO ZERO Pointer
            gn = new LTrieGenerationNode(this._root);
            gn.Pointer = this._root.LinkToZeroNode;
            //gn.Value=0; - default
            _generationMap.Add(0, gn);

            gn.ReadSelf(useCache, _generationMap.GenerateMapNodesValuesUpToIndex(0));
            //}

            //ulong cnt = 0; //NEED ONLY FOR SKIP

            byte[] generationMapLine = new byte[1] { 0 };
            byte[] gml = null;
            LTrieGenerationNode gn1 = null;
            byte[] key = null;
            LTrieRow row = null;

            //Starting from first key. It's interesting inside of RecursiveYieldReturn to look Starting from value
            //If intialKey index already bigger then its own length
            //But for the first must be enough
            foreach (var kd in gn.KidsInNode.GetKidsForward(initialKey[0]))
            {
                if (kd.Val != initKey[0])
                    continue;

                //Console.WriteLine("KN: {0}", key.ToBytesString(""));

                //Kid can be value link or node link
                //if value link we can count 1 up
                if (kd.ValueKid || !kd.LinkToNode)
                {
                    key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr);

                    if (key.IfStringArrayStartsWith(initialKey))
                    {
                        //cnt++;
                        row = new LTrieRow(this._root);
                        row.Key = key;
                        row.LinkToValue = kd.Ptr;
                        yield return row;
                    }
                }
                else
                {
                    gn1 = new LTrieGenerationNode(this._root);
                    gn1.Pointer = kd.Ptr;
                    gn1.Value = (byte)kd.Val;
                    //increasing map line must hold already 2 elements
                    gml = generationMapLine.Concat(gn1.Value);
                    gn1.ReadSelf(useCache, gml);
                    //generationMapLine = generationMapLine.Concat(gn1.Value);
                    //gn1.ReadSelf(useCache, generationMapLine);

                    //foreach (var xr in ItFrwStartsWith(gn1, generationMapLine, 1, true, useCache))
                    foreach (var xr in ItFrwStartsWith(gn1, gml, 1, useCache))
                    {
                        yield return xr;
                    }
                }
            }

            //Console.WriteLine("CNT: {0}", cnt);
        }
示例#14
0
        public IEnumerable<LTrieRow> IterateForwardSkipFrom(byte[] initKey, ulong skippingQuantity, bool useCache)
        {
            LTrieGenerationNode gn = null;

            initialKey = initKey;

            skippingTotal = skippingQuantity;

            LTrieGenerationMap _generationMap = new LTrieGenerationMap();

            //if (_generationMap.Count() == 0)
            //{
                //Loading it from Link TO ZERO Pointer
                gn = new LTrieGenerationNode(this._root);
                gn.Pointer = this._root.LinkToZeroNode;
                //gn.Value=0; - default
                _generationMap.Add(0, gn);

                gn.ReadSelf(useCache, _generationMap.GenerateMapNodesValuesUpToIndex(0));
            //}

            //ulong cnt = 0; //NEED ONLY FOR SKIP

            byte[] generationMapLine = new byte[1] { 0 };
            byte[] gml = null;
            LTrieGenerationNode gn1 = null;
            byte[] key = null;
            LTrieRow row = null;
            long valueStartPtr = 0;
            uint valueLength = 0;
            byte[] xValue = null;

            //Starting from first key. It's interesting inside of RecursiveYieldReturn to look Starting from value
            //If intialKey index already bigger then its own length
            //But for the first must be enough
            foreach (var kd in gn.KidsInNode.GetKidsForward(initialKey[0]))
            {
                //Console.WriteLine("KN: {0}", key.ToBytesString(""));

                //Kid can be value link or node link
                //if value link we can count 1 up
                if (kd.ValueKid || !kd.LinkToNode)
                {

                    if (keyIsFound)
                    {
                        //We return this one key, if quantity of skips is enough
                        skippedCnt++;

                        if (skippedCnt > skippingTotal)
                        {
                            if (ReturnKeyValuePair)
                            {
                                this._root.Tree.Cache.ReadKeyValue(useCache, kd.Ptr, out valueStartPtr, out valueLength, out key, out xValue);
                            }
                            else
                            {
                                key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr);
                            }

                            //cnt++;
                            row = new LTrieRow(this._root);
                            if (ReturnKeyValuePair)
                            {
                                row.ValueStartPointer = valueStartPtr;
                                row.ValueFullLength = valueLength;
                                row.Value = xValue;
                                row.ValueIsReadOut = true;
                            }
                            row.Key = key;
                            row.LinkToValue = kd.Ptr;
                            yield return row;
                        }
                    }
                    else
                    {
                        key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr);

                        //Checking if key equals to the found element, bigger or smaller

                        //Key is still not found

                        if (key.IfStringArrayBiggerOrEqualThen(initialKey))
                        {
                            keyIsFound = true;

                            //case if Startkey doesn't exist, then first encountered value can be calculated as first for skipping
                            if (key.IfStringArrayBiggerThen(initialKey))
                            {
                                skippedCnt++;

                                if (skippedCnt > skippingTotal)
                                {
                                    //key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr);

                                    row = new LTrieRow(this._root);
                                    row.Key = key;
                                    row.LinkToValue = kd.Ptr;
                                    yield return row;
                                }
                            }
                        }
                    }
                }
                else
                {
                    //special case when from key doesn't exist
                    if (initialKey[0] < kd.Val)
                        keyIsFound = true;

                    gn1 = new LTrieGenerationNode(this._root);
                    gn1.Pointer = kd.Ptr;
                    gn1.Value = (byte)kd.Val;
                    //increasing map line must hold already 2 elements
                    gml = generationMapLine.Concat(gn1.Value);
                    gn1.ReadSelf(useCache, gml);
                    //generationMapLine = generationMapLine.Concat(gn1.Value);
                    //gn1.ReadSelf(useCache, generationMapLine);

                    //foreach (var xr in ItFrwSkipFrom(gn1, generationMapLine, useCache))
                    foreach (var xr in ItFrwSkipFrom(gn1, gml, useCache))
                    {
                        //cnt++;      //NEED ONLY FOR SKIP
                        yield return xr;
                    }
                }
            }

            //Console.WriteLine("CNT: {0}", cnt);
        }
示例#15
0
        private IEnumerable<LTrieRow> ItFrwStartsWith_Prefix_Helper(LTrieGenerationNode gn, byte[] generationMapLine, int deep, bool useCache)
        {
            byte[] key = null;
            LTrieRow row = null;

            byte[] gml = null;

            foreach (var kd in gn.KidsInNode.GetKidsForward())
            {

                //deep corresponds to search key(initialKey) index for compare value
                //deep can be bigger then initKey
                //in small deep kd.Value can represent link to node

                if (deep > (initialKey.Length - 1))
                {
                    //DOING NOTHING

                    //////we are bigger then supplied key for search (initialKey)
                    ////if (kd.ValueKid || !kd.LinkToNode)
                    ////{
                    ////    //visualize all possible

                    ////    key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr);
                    ////    row = new LTrieRow(this._root);
                    ////    row.Key = key;
                    ////    row.LinkToValue = kd.Ptr;
                    ////    yield return row;
                    ////}
                    ////else
                    ////{
                    ////    //grow with ability to show all
                    ////    LTrieGenerationNode gn1 = new LTrieGenerationNode(this._root);
                    ////    gn1.Pointer = kd.Ptr;
                    ////    gn1.Value = (byte)kd.Val;
                    ////    gml = generationMapLine.Concat(gn1.Value);
                    ////    gn1.ReadSelf(useCache, gml);

                    ////    foreach (var xr in ItFrwStartsWith_Prefix_Helper(gn1, gml, deep + 1, useCache))
                    ////    {
                    ////        yield return xr;
                    ////    }
                    ////}
                }
                else
                {
                    //search indexes still cooresponds to data

                    if (kd.Val == initialKey[deep]) //and we can compare every supplied byte with index
                    {
                        if (deep == (initialKey.Length - 1))
                        {
                            //final index length value
                            if (kd.ValueKid || !kd.LinkToNode)
                            {
                                PrefixDeep++;

                                ////visualize

                                //key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr);

                                //row = new LTrieRow(this._root);
                                //row.Key = key;
                                //row.LinkToValue = kd.Ptr;
                                //yield return row;

                            }
                            else
                            {
                                PrefixDeep++;

                                ////grow with ability to show all
                                //LTrieGenerationNode gn1 = new LTrieGenerationNode(this._root);
                                //gn1.Pointer = kd.Ptr;
                                //gn1.Value = (byte)kd.Val;
                                //gml = generationMapLine.Concat(gn1.Value);
                                //gn1.ReadSelf(useCache, gml);

                                //foreach (var xr in ItFrwStartsWith_Prefix_Helper(gn1, gml, deep + 1, useCache))
                                //{
                                //    yield return xr;
                                //}
                            }
                        }
                        else
                        {
                            //smaller then final index length

                            if (kd.ValueKid || !kd.LinkToNode)
                            {
                                //do nothing in case of ValueKid
                                if (!kd.ValueKid)
                                {
                                    PrefixDeep++;
                                    ////Link to Value, probably this value suits to us
                                    //key = this._root.Tree.Cache.ReadKey(useCache, kd.Ptr);

                                    //if (key.IfStringArrayStartsWith(initialKey))
                                    //{
                                    //    //visualize

                                    //    row = new LTrieRow(this._root);
                                    //    row.Key = key;
                                    //    row.LinkToValue = kd.Ptr;
                                    //    yield return row;
                                    //}

                                }
                            }
                            else
                            {
                                PrefixDeep++;

                                //grow up
                                LTrieGenerationNode gn1 = new LTrieGenerationNode(this._root);
                                gn1.Pointer = kd.Ptr;
                                gn1.Value = (byte)kd.Val;
                                gml = generationMapLine.Concat(gn1.Value);
                                gn1.ReadSelf(useCache, gml);

                                foreach (var xr in ItFrwStartsWith_Prefix_Helper(gn1, gml, deep + 1, useCache))
                                {
                                   yield return xr;
                                }
                            }
                        }

                    }
                    else
                    {
                        //do nothing
                    }
                }

            }
        }