예제 #1
0
        public LTrieKid GetKid(int kid)
        {
            LTrieKid kidDef = new LTrieKid();

            //Check if it's used somewhere
            kidDef.Val = kid;

            kid++;  //bringing kid to the real value
            int kidPlace = kid * shift;

            if (_f[kidPlace] == 1)
            {
                kidDef.Exists = true;

                if (_f[kidPlace + 1] == 1)
                {
                    kidDef.LinkToNode = false;          //Link to Value
                }
                kidDef.Ptr = new byte[DefaultPointerLength];

                Buffer.BlockCopy(_f, (kidPlace + 2), kidDef.Ptr, 0, DefaultPointerLength);

                //for (int i = 0; i < DefaultPointerLength; i++)          //Can be changed on substring
                //{
                //    kidDef.Ptr[i] = _f[(kidPlace + 2) + i];
                //}
            }

            return(kidDef);
        }
예제 #2
0
        public IEnumerable <LTrieKid> GetKidsBackward(int startFrom)
        {
            LTrieKid ret = null;

            if (this.count > 0 && startFrom != 256)
            {
                startFrom += 1;

                int kidPlace = 0;
                for (int i = startFrom; i > 0; i--)
                {
                    kidPlace = i * shift;

                    if (_f[kidPlace] == 1)
                    {
                        ret        = new LTrieKid();
                        ret.Exists = true;
                        ret.Val    = i - 1;

                        ret.Ptr = new byte[DefaultPointerLength];
                        for (int j = 0; j < DefaultPointerLength; j++)          //Can be changed on substring
                        {
                            ret.Ptr[j] = _f[(kidPlace + 2) + j];
                        }

                        //Setting up link to Node or to Value
                        if (_f[kidPlace + 1] == 1)
                        {
                            ret.LinkToNode = false;
                        }

                        yield return(ret);
                    }
                }
            }

            if (!ValueIsEmpty)
            {
                ret = new LTrieKid();

                //trying to take max kid
                ret.Ptr      = PtrToValue;
                ret.Exists   = true;
                ret.ValueKid = true;
                ret.Val      = 256;

                yield return(ret);
            }
        }
예제 #3
0
        /// <summary>
        /// Gets Value kid (before 0-255)
        /// </summary>
        /// <returns></returns>
        public LTrieKid GetKidValue()
        {
            LTrieKid kidDef = new LTrieKid();

            kidDef.ValueKid = true;

            if (ValueIsEmpty)
            {
                return(kidDef);
            }

            kidDef.Exists = true;
            kidDef.Val    = 256;

            kidDef.Ptr = PtrToValue;
            return(kidDef);
        }
예제 #4
0
        public LTrieKid GetMinKid()
        {
            LTrieKid ret = new LTrieKid();

            if (!ValueIsEmpty)
            {
                //In case if we have value then it's a minimum

                ret.Ptr      = PtrToValue;
                ret.Exists   = true;
                ret.ValueKid = true;
                ret.Val      = 256;
            }
            else
            {
                SearchExtremums();

                if (MinKidNull)
                {
                    return(ret);
                }

                int kidPlace = MinKid * shift;


                ret.Exists = true;
                ret.Val    = MinKid - 1; //Bringing value to [0-255]

                //Copying Pointer
                ret.Ptr = new byte[DefaultPointerLength];

                for (int i = 0; i < DefaultPointerLength; i++)          //Can be changed on substring
                {
                    ret.Ptr[i] = _f[(kidPlace + 2) + i];
                }

                //Setting up link to Node or to Value
                if (_f[kidPlace + 1] == 1)
                {
                    ret.LinkToNode = false;
                }
            }

            return(ret);
        }
예제 #5
0
        //public LTrieKid GetKidBiggerThen(int kid)
        //{
        //    LTrieKid ret = new LTrieKid();

        //    kid += 2;

        //    if (kid > 256)
        //        return ret;

        //    int kidPlace = 0;

        //    for (int i = kid; i <= 256; i++) //i<257
        //    {
        //        kidPlace = i * shift;
        //        if (_f[kidPlace] == 1)
        //        {
        //            ret.Exists = true;
        //            ret.Val = i - 1;

        //            ret.Ptr = new byte[DefaultPointerLength];
        //            for (int j = 0; j < DefaultPointerLength; j++)          //Can be changed on substring
        //            {
        //                ret.Ptr[j] = _f[(kidPlace + 2) + j];
        //            }

        //            //Setting up link to Node or to Value
        //            if (_f[kidPlace + 1] == 1)
        //                ret.LinkToNode = false;

        //            return ret;
        //        }
        //    }

        //    return ret;
        //}

        public IEnumerable <LTrieKid> GetKidsForward(int startFrom)
        {
            LTrieKid ret = null;

            //USE it later if startFrom = 256
            if (startFrom == 256)
            {
                if (!ValueIsEmpty)
                {
                    ret = new LTrieKid();

                    //trying to take max kid
                    ret.Ptr      = PtrToValue;
                    ret.Exists   = true;
                    ret.ValueKid = true;
                    ret.Val      = 256;

                    yield return(ret);
                }

                startFrom = 0;
            }

            if (this.count > 0)
            {
                //Change back kid to normal
                startFrom += 1;


                //if (startFrom == 256)
                //    startFrom = 1;
                //else
                //    startFrom += 1;

                int kidPlace = 0;
                for (int i = startFrom; i <= 256; i++)
                {
                    kidPlace = i * shift;

                    if (_f[kidPlace] == 1)
                    {
                        ret        = new LTrieKid();
                        ret.Exists = true;
                        ret.Val    = i - 1;

                        ret.Ptr = new byte[DefaultPointerLength];
                        for (int j = 0; j < DefaultPointerLength; j++)          //Can be changed on substring
                        {
                            ret.Ptr[j] = _f[(kidPlace + 2) + j];
                        }

                        //Setting up link to Node or to Value
                        if (_f[kidPlace + 1] == 1)
                        {
                            ret.LinkToNode = false;
                        }

                        yield return(ret);
                    }
                }
            }
        }
예제 #6
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>
        /// <param name="useCache"></param>
        /// <param name="ValuesLazyLoadingIsOn">if true reads key only</param>
        /// <returns></returns>
        public LTrieRow GetKey(byte[] key, bool useCache, bool ValuesLazyLoadingIsOn)
        {
            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 (!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 (!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);
        }