Пример #1
0
        //internal bool IfWriteThread()
        //{
        //    return (_masterTrie.NestedTablesCoordinator.ModificationThreadId == System.Threading.Thread.CurrentThread.ManagedThreadId);
        //}


        internal NestedTable GetTable <TKey>(TKey key, uint tableIndex, bool insertIsAllowed)
        {
            byte[]   btKey = DataTypesConvertor.ConvertKey <TKey>(key);
            LTrieRow row   = null;

            if (insertIsAllowed)        //Insert of table is allowed by calls generation
            {
                row = table.GetKey(ref btKey, null);
                return(table.GetTable(row, ref btKey, tableIndex, this._masterTrie, true, false));
            }

            //Only selects are allowed

            if (_masterTrie.NestedTablesCoordinator.ModificationThreadId == System.Threading.Thread.CurrentThread.ManagedThreadId)
            {
                //This thread must NOT use cache
                row = table.GetKey(ref btKey, null);
                return(table.GetTable(row, ref btKey, tableIndex, this._masterTrie, false, false));
            }
            else
            {
                LTrieRootNode readRootNode = new LTrieRootNode(table);
                row = table.GetKey(ref btKey, readRootNode);

                return(table.GetTable(row, ref btKey, tableIndex, this._masterTrie, false, true));
            }
        }
Пример #2
0
        private void ReadUserLastFileNumber()
        {
            byte[]   btKeyName = Encoding.UTF8.GetBytes(LastFileNumberKeyName);
            LTrieRow row       = LTrie.GetKey(btKeyName, false, false);

            if (row.Exists)
            {
                byte[] fullValue = row.GetFullValue(true);
                LastFileNumber = fullValue.To_UInt64_BigEndian();
            }
        }
Пример #3
0
        /// <summary>
        /// Returns physical path to the table file, if table doesn't exists in the Scheme returns String.Empty
        /// </summary>
        /// <param name="userTableName"></param>
        /// <returns></returns>
        public string GetTablePathFromTableName(string userTableName)
        {
            //For user usage

            _sync_openTablesHolder.EnterReadLock();
            try
            {
                byte[] btTableName = GetUserTableNameAsByte(userTableName);

                LTrieRow row = LTrie.GetKey(btTableName, true, false);

                if (!row.Exists)
                {
                    return(String.Empty);
                }

                byte[] fullValue = row.GetFullValue(true);
                //Can be parsed different. First protocol version is 1
                ushort schemeProtocol = fullValue.Substring(0, 2).To_UInt16_BigEndian();
                ulong  fileName       = 0;
                switch (schemeProtocol)
                {
                case 1:
                    fileName = fullValue.Substring(2, 8).To_UInt64_BigEndian();
                    break;

                default:
                    throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.SCHEME_FILE_PROTOCOL_IS_UNKNOWN);
                }

                string alternativeTableLocation = String.Empty;

                if (CheckAlternativeTableLocationsIntersections(userTableName, out alternativeTableLocation))
                {
                    if (alternativeTableLocation == String.Empty)
                    {
                        return("MEMORY");
                    }
                    else
                    {
                        return(Path.Combine(alternativeTableLocation, fileName.ToString()));
                    }
                }
                else
                {
                    return(Path.Combine(Engine.MainFolder, fileName.ToString()));
                }
            }
            finally
            {
                _sync_openTablesHolder.ExitReadLock();
            }
        }
Пример #4
0
        //byte[] btKey = null;

        public Row(LTrieRow row, LTrie masterTrie, bool useCache)
        {
            if (row == null)
            {
                _exists = false;
            }
            else
            {
                _row = row;
                //_root = row._root;
                //_ptrToValue = row.LinkToValue;
                _exists = row.Exists;
            }
            _useCache   = useCache;
            _masterTrie = masterTrie;

            if (_exists)
            {
                _key = DataTypesConvertor.ConvertBack <TKey>(row.Key);
            }
        }
Пример #5
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;
                    }
                }
            }
        }
Пример #6
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;
                    }
                }
            }
        }
Пример #7
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);
        }
Пример #8
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);
        }
Пример #9
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);
        }
Пример #10
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
                    }
                }

            }
        }
Пример #11
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;
                    }
                }
            }
        }
Пример #12
0
        /// <summary>
        /// Returns table for READ, WRITE FUNC
        /// </summary>
        /// <param name="userTableName"></param>
        /// <returns></returns>
        internal LTrie GetTable(string userTableName)
        {
            string tableName = GetUserTableNameAsString(userTableName);

            //TODO pattern based mapping If table doesn't exist we create it with properties which could be supplied after db init as regex theme.



            //Schema protocol: 2 bytes - protocol version, other data
            //For protocol 1: first 8 bytes will be TheFileName, starting from db10000-dbN (0-N ulong). up to 10000 are reserved for dbreeze.

            //Table names are UTF-8 based, no limits

            ulong     fileName = 0;
            OpenTable otl      = null;

            _sync_openTablesHolder.EnterUpgradeableReadLock();
            try
            {
                _openTablesHolder.TryGetValue(tableName, out otl);

                if (otl != null)
                {
                    //Try to increase usage and return LTrie
                    otl.Add();
                    return(otl.Trie);
                }


                //Probably table Exists in db but not in openTablesHolder

                _sync_openTablesHolder.EnterWriteLock();
                try
                {
                    //UpgradeableRead recheck
                    _openTablesHolder.TryGetValue(tableName, out otl);

                    if (otl != null)
                    {
                        //Try to increase usage and return LTrie
                        otl.Add();
                        return(otl.Trie);
                    }



                    byte[] btTableName = GetUserTableNameAsByte(userTableName);

                    //Trying to get fileName from cache
                    fileName = this.cachedTableNames.GetFileName(tableName);
                    // LTrieRow row = null;
                    bool tableExists = false;

                    if (fileName == 0)
                    {
                        LTrieRow row = LTrie.GetKey(btTableName, false, false);


                        if (row.Exists)
                        {
                            tableExists = true;

                            byte[] fullValue = row.GetFullValue(false);
                            //Can be parsed different. First protocol version is 1
                            ushort schemeProtocol = fullValue.Substring(0, 2).To_UInt16_BigEndian();

                            switch (schemeProtocol)
                            {
                            case 1:
                                fileName = fullValue.Substring(2, 8).To_UInt64_BigEndian();
                                break;

                            default:
                                throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.SCHEME_FILE_PROTOCOL_IS_UNKNOWN);
                            }
                        }
                        else
                        {
                            tableExists = false;
                            //Creating new table.

                            //Checking table name validity

                            //this will throw exception, if not valid
                            DbUserTables.UserTableNameIsOk(userTableName);


                            //Creating such table and renewing LastFileNumber counter

                            //Adding to LastFileNumber
                            LastFileNumber++;


                            ////Deleting physical files related to the table, if they existed - normally they should not
                            //DeleteAllReleatedTableFiles(Path.Combine(Engine.MainFolder, LastFileNumber.ToString()));

                            byte[] lft = LastFileNumber.To_8_bytes_array_BigEndian();

                            //Writing this number to Schema file
                            LTrie.Add(Encoding.UTF8.GetBytes(LastFileNumberKeyName), lft);

                            //Creating table self and writing to Schema file

                            LTrie.Add(btTableName,
                                      new byte[] { 0, 1 } //Protocol version 1
                                      .Concat(lft));    //Number of the file

                            //Committing both records
                            LTrie.Commit();

                            fileName = LastFileNumber;

                            this.cachedTableNames.Add(tableName, fileName);
                        }
                    }
                    else
                    {
                        tableExists = true;
                    }

                    //Creating LTrie, adding it to _openTablesHolder

                    //Seeting up Trie TableName, OTHER SETTINGS

                    TrieSettings ts      = new TrieSettings();
                    IStorage     storage = null;


                    ////Checking if default Flusg Disk behaviour was overriden
                    //ts.DiskFlushBehaviour = Engine.Configuration.DiskFlushBehaviour;
                    ////Checking if we have alternative DiskFlush behaviour
                    //foreach (var pattern in Engine.Configuration.AlternativeDiskFlushBehaviour)
                    //{
                    //    //pattern.Key
                    //    if (DbUserTables.PatternsIntersect(pattern.Key, userTableName))
                    //    {

                    //        ts.DiskFlushBehaviour = pattern.Value;
                    //        break;
                    //    }
                    //}

                    string alternativeTableLocation = String.Empty;

                    if (CheckAlternativeTableLocationsIntersections(userTableName, out alternativeTableLocation))
                    {
                        ts.StorageWasOverriden = true;

                        if (alternativeTableLocation == String.Empty)
                        {
                            ts.AlternativeTableStorageType = DBreezeConfiguration.eStorage.MEMORY;

                            storage = new StorageLayer(Path.Combine(Engine.MainFolder, fileName.ToString()), ts, Engine.Configuration);
                        }
                        else
                        {
                            ts.AlternativeTableStorageType   = DBreezeConfiguration.eStorage.DISK;
                            ts.AlternativeTableStorageFolder = alternativeTableLocation;

                            DirectoryInfo diAlt = new DirectoryInfo(alternativeTableLocation);
                            if (!diAlt.Exists)
                            {
                                diAlt.Create();
                            }

                            if (!tableExists)
                            {
                                //Deleting physical files related to the table, if they existed - normally they should not
                                DeleteAllReleatedTableFiles(Path.Combine(ts.AlternativeTableStorageFolder, LastFileNumber.ToString()));
                            }

                            storage = new StorageLayer(Path.Combine(ts.AlternativeTableStorageFolder, fileName.ToString()), ts, Engine.Configuration);
                        }
                    }
                    else
                    {
                        if (!tableExists)
                        {
                            //Deleting physical files related to the table, if they existed - normally they should not
                            DeleteAllReleatedTableFiles(Path.Combine(Engine.MainFolder, LastFileNumber.ToString()));
                        }

                        storage = new StorageLayer(Path.Combine(Engine.MainFolder, fileName.ToString()), ts, Engine.Configuration);
                    }

                    //storage = new StorageLayer(Path.Combine(Engine.MainFolder, fileName.ToString()), ts, Engine.Configuration);

                    LTrie trie = new LTrie(storage);

                    //Setting LTrie user table name
                    trie.TableName = userTableName;

                    //_openTablesHolder.Add(tableName, trie);

                    //Automatically increased usage in OpenTable constructor
                    _openTablesHolder.Add(tableName, new OpenTable(trie));

                    return(trie);
                }
                catch (System.Exception ex)
                {
                    //CASCADE
                    throw ex;
                }
                finally
                {
                    _sync_openTablesHolder.ExitWriteLock();
                }
            }
            catch (Exception ex)
            {
                throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.SCHEME_GET_TABLE_WRITE_FAILED, tableName, ex);
            }
            finally
            {
                _sync_openTablesHolder.ExitUpgradeableReadLock();
            }
        }
Пример #13
0
        /// <summary>
        /// ONLY FOR INTERNAL NEEDS, lock must be handeled by outer procedure.
        /// Users must use GetTablePathFromTableName.
        /// Transactions Journal after start will try to delete RollbackFiles of the finished transactions.
        /// For this it needs to know exact pathes.
        /// For now all tables stored in one folder. Later we will have extra config file which lets to reside
        /// some of tables in the other folders.
        /// This function is an access globalizer to physical file locations by userTableName.
        /// !!!!TRAnJRNL, WHEN RESTORES ROLLBACK, MUST REFER TO Scheme trie settings in the future, FOR NOW DEFAULT
        /// </summary>
        /// <param name="userTableName"></param>
        /// <returns></returns>
        internal string GetPhysicalPathToTheUserTable(string userTableName)
        {
            try
            {
                byte[] btTableName = GetUserTableNameAsByte(userTableName);
                ulong  fileName    = 0;


                //Getting file name
                LTrieRow row = LTrie.GetKey(btTableName, false, false);

                if (row.Exists)
                {
                    byte[] fullValue = row.GetFullValue(true);
                    //Can be parsed different. First protocol version is 1
                    ushort schemeProtocol = fullValue.Substring(0, 2).To_UInt16_BigEndian();

                    switch (schemeProtocol)
                    {
                    case 1:
                        fileName = fullValue.Substring(2, 8).To_UInt64_BigEndian();
                        break;

                    default:
                        throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.SCHEME_FILE_PROTOCOL_IS_UNKNOWN);
                    }
                }
                else
                {
                    return(String.Empty);
                }


                //Getting folder

                //For now returns path inside working folder, later re-make, take into consideration mapping of DB to tother folders.

                string alternativeTableLocation = String.Empty;

                if (CheckAlternativeTableLocationsIntersections(userTableName, out alternativeTableLocation))
                {
                    if (alternativeTableLocation == String.Empty)
                    {
                        //In memory table
                        //return Path.Combine(Engine.MainFolder, fileName.ToString());
                        return("MEMORY");
                    }
                    else
                    {
                        //returning alternative folder + fileName
                        return(Path.Combine(alternativeTableLocation, fileName.ToString()));
                    }
                }
                else
                {
                    //Standard path (Dbreeze mainFolder + fileName)
                    return(Path.Combine(Engine.MainFolder, fileName.ToString()));
                }
            }
            //catch (System.Threading.ThreadAbortException ex)
            //{
            //    //We don'T make DBisOperable = false;
            //    throw ex;
            //}
            catch (Exception ex)
            {
                this.Engine.DBisOperable       = false;
                this.Engine.DBisOperableReason = "GetPhysicalPathToTheUserTable";
                throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.GENERAL_EXCEPTION_DB_NOT_OPERABLE, this.Engine.DBisOperableReason, ex);
            }
        }
Пример #14
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);
        }
Пример #15
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);
        }