Example #1
0
        public TextDeferredIndexer(DBreezeEngine engine)
        {
            this.DBreezeEngine = engine;
            LTrieSettings      = new TrieSettings()
            {
                InternalTable = true
            };
            Storage         = new StorageLayer(Path.Combine(engine.MainFolder, TableFileName), LTrieSettings, engine.Configuration);
            LTrie           = new LTrie(Storage);
            LTrie.TableName = "DBreeze.TextIndexer";

            if (LTrie.Storage.Length > 100000)  //Recreating file if its size more then 100KB and it is empty
            {
                if (LTrie.Count(true) == 0)
                {
                    LTrie.Storage.RecreateFiles();
                    LTrie.Dispose();

                    Storage         = new StorageLayer(Path.Combine(engine.MainFolder, TableFileName), LTrieSettings, engine.Configuration);
                    LTrie           = new LTrie(Storage);
                    LTrie.TableName = "DBreeze.TextIndexer";
                }
            }

            if (LTrie.Count(true) > 0)
            {
                this.StartDefferedIndexing();
            }
        }
Example #2
0
        public NestedTableInternal(bool tableExists, LTrie masterTrie, long rootStart, long shiftFromValueStart, bool useCache, LTrie parentTrie, ref byte[] key)
        {
            //DbInTableStorage - Dispose and Recreate (Stay Empty)

            /////////////////////////////////   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!     GET RID OF , bool useCache
            /////////////////////////////////   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!     GET RID OF MASTER TABLE INSERT (table can be created by read thread also)

            TableExists = tableExists;

            if (tableExists)
            {
                _useCache            = useCache;
                _shiftFromValueStart = shiftFromValueStart;
                //Flag distinguish between masterTrie.InsertTable or masterTrie.SelectTable (InsertTable, creates tables if they don't exist)
                //_masterTableInsert = masterTableInsert;
                _masterTrie  = masterTrie;
                _parentTable = parentTrie;
                _key         = key;
                _rootStart   = rootStart;


                TrieSettings trieSettings = new TrieSettings()
                {
                    ROOT_START    = rootStart,
                    IsNestedTable = true
                };

                _storage = new NestedTableStorage(masterTrie.Cache.Trie.Storage, trieSettings);

                //Then trie receives ITableFile wrapper with new settings

                table = new LTrie(_storage);
            }
        }
Example #3
0
        /// <summary>
        /// Reclaim unused space (Directly on the table, stopping the defragmentation can result in permanent corruption)
        /// </summary>
        /// <returns>The number of bytes saved</returns>
        public async ValueTask <int> UnsafeDefragment(CancellationToken cancellationToken = default)
        {
            ClearTrie();
            await ClearFileStream();

            int saved    = 0;
            var fileName = await tx.Schema.GetFileNameOrCreate(tableName);

            if (!await tx._Engine.Storages.Exists(fileName.ToString()))
            {
                return(0);
            }
            await using var fs = await tx._Engine.Storages.OpenStorage(fileName.ToString());

            await using var cache = new CacheStorage(fs, false, PagePool, true);
            var trie = await LTrie.OpenFromStorage(cache);

            saved = await trie.Defragment(cancellationToken);

            await cache.Flush();

            await fs.Flush();

            return(saved);
        }
Example #4
0
        /// <summary>
        /// Can return NULL (if DbIsNotOperatable)
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="transactionThreadId"></param>
        /// <returns></returns>
        public LTrie GetTable_WRITE(string tableName, int transactionThreadId)
        {
            if (!this._engine.DBisOperable)
            {
                return(null);
            }

            TransactionUnit transactionUnit = this.GetTransactionUnit(transactionThreadId);

            if (transactionUnit != null)
            {
#if NET35 || NETr40
                if (System.Threading.Thread.CurrentThread.ManagedThreadId != transactionThreadId)
#else
                if (Environment.CurrentManagedThreadId != transactionThreadId)
#endif
                {
                    this.UnregisterTransaction(transactionThreadId);

                    throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.TRANSACTION_CANBEUSED_FROM_ONE_THREAD);
                }


                //We must put Get_Table_Write through the same bottleneck as RegisterWriteTablesForTransaction
                this.RegisterWriteTablesForTransaction(transactionThreadId, new List <string> {
                    tableName
                }, false);
                //it will wait here till table for writing, reserved by other thread is released

                LTrie tbl = null;

                try
                {
                    tbl = this._engine.DBreezeSchema.GetTable(tableName);

                    //Adding table to transaction unit with the ITransactable interface
                    transactionUnit.AddTransactionWriteTable(tableName, tbl);    //added together with ITransactable

                    //TODO  -   THIS TABLE LTrie must be Interfaced
                    //Telling to the table that transactionThreadId Thread will modify it
                    tbl.ModificationThreadId(transactionThreadId);
                }
                catch (Exception ex)
                {
                    //Exception must come from Schema, by in-ability to get the table
                    this.UnregisterTransaction(transactionThreadId);

                    //CIRCULAR PARTLY
                    throw ex;
                }

                return(tbl);
            }
            else
            {
                throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.TRANSACTION_DOESNT_EXIST);
            }
        }
Example #5
0
        /// <summary>
        /// Flushing all
        /// </summary>
        public void Flush()
        {
            if (!isUsed)
            {
                return;
            }

            LTrie table       = null;
            bool  WasOperated = false;

            byte[] deletedValue = null;
            byte[] btKey        = null;
            byte[] btVal        = null;

            foreach (var el1 in _dRemove.OrderBy(r => r.Key))
            {
                if (!tbls.TryGetValue(el1.Key, out table))
                {
                    table         = _t.GetWriteTableFromBuffer(el1.Key);
                    tbls[el1.Key] = table;
                }

                foreach (var el2 in el1.Value.OrderBy(r => r.Key))
                {
                    //_t.RemoveKey<byte[]>(el1.Key, el2.Value);
                    btKey = el2.Value;
                    table.Remove(ref btKey, out WasOperated, false, out deletedValue);
                }
            }

            _dRemove.Clear();

            foreach (var el1 in _dInsert.OrderBy(r => r.Key))
            {
                if (!tbls.TryGetValue(el1.Key, out table))
                {
                    table         = _t.GetWriteTableFromBuffer(el1.Key);
                    tbls[el1.Key] = table;
                }

                //List<string> tt = el1.Value.OrderBy(r => r.Key).Select(r => r.Key).ToList();
                foreach (var el2 in el1.Value.OrderBy(r => r.Key))
                {
                    //_t.Insert<byte[], byte[]>(el1.Key, el2.Value.Key, el2.Value.Value);
                    btKey = el2.Value.Key;
                    btVal = el2.Value.Value;
                    table.Add(ref btKey, ref btVal, out WasOperated, false);
                }
            }

            _dInsert.Clear();
            _cnt.Clear();

            WasAutomaticallyFlushed = false;

            isUsed = false;
        }
Example #6
0
 public void Setup()
 {
     t = new Tester();
     t.ConsistencyCheck = false;
     key  = Encoding.UTF8.GetBytes("cf6c9e8cb9fb312862edbd5c2b7d1615db4f65ab");
     fs   = t.CreateFileStorage("10000007", true, "Benchmark");
     trie = t.CreateTrie(fs, false).GetAwaiter().GetResult();
     (trie.EnumerateStartsWith("").ToArrayAsync().GetAwaiter().GetResult()).DisposeAll();
 }
Example #7
0
 /// <summary>
 /// constructor
 /// </summary>
 /// <param name="engine"></param>
 internal DBreezeResources(DBreezeEngine engine)
 {
     this.DBreezeEngine = engine;
     LTrieSettings      = new TrieSettings()
     {
         InternalTable = true
     };
     Storage         = new StorageLayer(Path.Combine(engine.MainFolder, TableFileName), LTrieSettings, engine.Configuration);
     LTrie           = new LTrie(Storage);
     LTrie.TableName = "DBreezeResources";
 }
Example #8
0
        internal async ValueTask <LTrie> GetTrie()
        {
            if (trie is LTrie)
            {
                return(trie);
            }
            AssertNotClosed();
            trie = await LTrie.OpenOrInitFromStorage(await GetCacheStorage());

            trie.ConsistencyCheck = checkConsistency;
            return(trie);
        }
Example #9
0
        public void Flush(string tableName)
        {
            LTrie table       = null;
            bool  WasOperated = false;

            byte[] deletedValue = null;
            byte[] btKey        = null;
            byte[] btVal        = null;

            if (_dRemove.ContainsKey(tableName))
            {
                if (!tbls.TryGetValue(tableName, out table))
                {
                    table           = _t.GetWriteTableFromBuffer(tableName);
                    tbls[tableName] = table;
                }

                foreach (var el2 in _dRemove[tableName].OrderBy(r => r.Key))
                {
                    // _t.RemoveKey<byte[]>(tableName, el2.Value);
                    btKey = el2.Value;
                    table.Remove(ref btKey, out WasOperated, false, out deletedValue);
                }

                _dRemove[tableName].Clear();
                _dRemove.Remove(tableName);
            }

            if (_dInsert.ContainsKey(tableName))
            {
                if (!tbls.TryGetValue(tableName, out table))
                {
                    table           = _t.GetWriteTableFromBuffer(tableName);
                    tbls[tableName] = table;
                }

                foreach (var el2 in _dInsert[tableName].OrderBy(r => r.Key))
                {
                    //_t.Insert<byte[],byte[]>(tableName, el2.Value.Key, el2.Value.Value);
                    btKey = el2.Value.Key;
                    btVal = el2.Value.Value;
                    table.Add(ref btKey, ref btVal, out WasOperated, false);
                }
                _dInsert[tableName].Clear();
                _dInsert.Remove(tableName);
            }

            _cnt[tableName]         = 0;
            WasAutomaticallyFlushed = true;
        }
Example #10
0
        private static async ValueTask <DBTrieEngine> OpenFromStorages(IStorages storages)
        {
            if (storages == null)
            {
                throw new ArgumentNullException(nameof(storages));
            }
            var schemaFile = await storages.OpenStorage(Schema.StorageName);

            var trie = await LTrie.OpenOrInitFromStorage(schemaFile);

            var s = await Schema.OpenOrInitFromTrie(trie);

            return(new DBTrieEngine(storages, s));
        }
Example #11
0
        public LTrieRootNode(LTrie tree)
        {
            Tree = tree;
            DefaultPointerLen = Tree.Storage.TrieSettings.POINTER_LENGHT;
            DefaultRootSize   = Tree.Storage.TrieSettings.ROOT_SIZE;

            //me = new byte[Tree.Storage.TreeSettings.ROOT_SIZE];
            LinkToZeroNode = new byte[DefaultPointerLen];

            this.EmptyPointer = new byte[DefaultPointerLen];

            //Reading Root Node
            this.ReadRootNode();
        }
Example #12
0
        /// <summary>
        /// Can return NULL if table doesn't exist
        /// Can return NULL (if DbIsNotOperatable)
        ///
        /// Differs from GetTable_Write:
        /// 1. table is not registered for Write;
        /// 2. Table is not created, if doesn't exist.
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="transactionThreadId"></param>
        /// <param name="ignoreThreadIdCheck"></param>
        /// <returns></returns>
        public LTrie GetTable_READ(string tableName, int transactionThreadId, bool ignoreThreadIdCheck = false)
        {
            if (!this._engine.DBisOperable)
            {
                return(null);
            }

            TransactionUnit transactionUnit = this.GetTransactionUnit(transactionThreadId);

            if (transactionUnit != null)
            {
#if NET35 || NETr40
                if (!ignoreThreadIdCheck && System.Threading.Thread.CurrentThread.ManagedThreadId != transactionThreadId)
#else
                if (!ignoreThreadIdCheck && Environment.CurrentManagedThreadId != transactionThreadId)
#endif
                {
                    this.UnregisterTransaction(transactionThreadId);
                    throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.TRANSACTION_CANBEUSED_FROM_ONE_THREAD);
                }

                LTrie tbl = null;

                try
                {
                    if (!this._engine.DBreezeSchema.IfUserTableExists(tableName))
                    {
                        return(null);
                    }

                    tbl = this._engine.DBreezeSchema.GetTable(tableName);
                }
                catch (Exception ex)
                {
                    //Exception must come from Schema, by in-ability to get the table
                    this.UnregisterTransaction(transactionThreadId);

                    //CIRCULAR PARTLY
                    throw ex;
                }

                return(tbl);
            }
            else
            {
                throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.TRANSACTION_DOESNT_EXIST);
            }
        }
Example #13
0
        /*          TODO
         *
         *  1. HERE we will add TableNames as RegEx with settings
         *  2. Checking Reserverd TableNames prefixes
         *  3. User TableName must start from @ut
         *  4. GetPhysicalPathToTheUserTable - File with DIrectory Settings for different tables parser (to make reside different tables in different HDDs or even network drives)
         */

        private void OpenSchema()
        {
            LTrieSettings = new TrieSettings()
            {
                InternalTable = true,
                //SkipStorageBuffer = true
            };

            Storage = new StorageLayer(Path.Combine(Engine.MainFolder, SchemaFileName), LTrieSettings, Engine.Configuration);

            LTrie = new LTrie(Storage);

            LTrie.TableName = "DBreeze.Scheme";

            //Reading lastFileNumber
            ReadUserLastFileNumber();
        }
Example #14
0
        internal static async ValueTask <Schema> OpenOrInitFromTrie(LTrie trie)
        {
            using var key = await trie.GetValue(LastFileNumberKey);

            ulong number = 10000000UL;

            if (key is LTrieValue)
            {
                number = await key.ReadValueULong();
            }
            else
            {
                await trie.SetValue(LastFileNumberKey, number);

                await trie.Storage.Flush();
            }
            return(new Schema(trie, number));
        }
Example #15
0
        /// <summary>
        /// Reclaim unused space (Copy the table in a temporary file, defragment and replace the original table)
        /// </summary>
        /// <returns>The number of bytes saved</returns>
        public async ValueTask <int> Defragment(CancellationToken cancellationToken = default)
        {
            ClearTrie();
            await ClearFileStream();

            // We copy the current table on a temporary file, then defragment that
            // once defragmentation is complete, we copy the temp file to the current table
            // this prevent corruption if anything happen on the middle of the defragmentation
            var fileName = await tx.Schema.GetFileNameOrCreate(tableName);

            var tmpFile = $"{fileName}_tmp";

            if (!await tx._Engine.Storages.Exists(fileName.ToString()))
            {
                return(0);
            }
            await tx._Engine.Storages.Copy(fileName.ToString(), tmpFile);

            int saved = 0;

            try
            {
                await using var fs = await tx._Engine.Storages.OpenStorage(tmpFile);

                await using var cache = new CacheStorage(fs, false, PagePool, true);
                var trie = await LTrie.OpenFromStorage(cache);

                saved = await trie.Defragment(cancellationToken);

                await cache.Flush();

                await fs.Flush();
            }
            catch
            {
                await tx._Engine.Storages.Delete(tmpFile);

                throw;
            }
            await tx._Engine.Storages.Move(tmpFile, fileName.ToString());

            return(saved);
        }
Example #16
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);
            }
        }
Example #17
0
        private void Init()
        {
            try
            {
                LTrieSettings = new TrieSettings()
                {
                    InternalTable = true,
                    //SkipStorageBuffer = true
                };

                Storage = new StorageLayer(Path.Combine(Engine.MainFolder, JournalFileName), LTrieSettings, Engine.Configuration);
                //Storage = new TrieDiskStorage(Path.Combine(Engine.MainFolder, JournalFileName), LTrieSettings, Engine.Configuration);
                LTrie = new LTrie(Storage);

                LTrie.TableName = "DBreeze.TranJournal";

                this.RestoreNotFinishedTransactions();
            }
            catch (Exception ex)
            {
                //CASCADE
                throw ex;
            }
        }
Example #18
0
        public void FinishTransaction(ulong tranNumber)
        {
            //_sync_transactionsTables.EnterReadLock();
            _sync_transactionsTables.EnterWriteLock();
            try
            {
                Dictionary <string, ITransactable> tbls = null;
                _transactionsTables.TryGetValue(tranNumber, out tbls);

                if (tbls != null)
                {
                    //Starting procedure

                    //1. Saving all table names into db - needed in case if something happens (Power loss or whatever).
                    //   Then restarted TransactionalJournal will delete rollback files for these tables (they are all committed)

                    List <string> committedTablesNames = new List <string>();
                    foreach (var tt in tbls)
                    {
                        committedTablesNames.Add(tt.Key);
                    }


                    string serTbls   = committedTablesNames.SerializeXml();
                    byte[] btSerTbls = System.Text.Encoding.UTF8.GetBytes(serTbls);

                    byte[] key = tranNumber.To_8_bytes_array_BigEndian();

                    LTrie.Add(ref key, ref btSerTbls);
                    LTrie.Commit();

                    //2. Calling transaction End for all tables
                    try
                    {
                        foreach (var tt in tbls)
                        {
                            tt.Value.ITRCommitFinished();
                        }
                    }
                    catch (Exception ex)
                    {
                        //CASCADE from ITRCommitFinished, brings to NON-OPERATABLE
                        throw ex;
                    }

                    //3. Deleting Record in Journal
                    LTrie.Remove(ref key);
                    LTrie.Commit();

                    //Clearing transaction number
                    tbls.Clear();
                    _transactionsTables.Remove(tranNumber);


                    //When Transaction File becomes big we try to clean it.
                    if (LTrie.Storage.Length > MaxlengthOfTransactionFile && _transactionsTables.Count() == 0)
                    {
                        LTrie.Storage.RecreateFiles();
                        LTrie.Dispose();

                        Storage         = new StorageLayer(Path.Combine(Engine.MainFolder, JournalFileName), LTrieSettings, Engine.Configuration);
                        LTrie           = new LTrie(Storage);
                        LTrie.TableName = "DBreeze.TranJournal";
                    }
                }
            }
            catch (System.Exception ex)
            {
                //CASCADE
                throw ex;
            }
            finally
            {
                _sync_transactionsTables.ExitWriteLock();
                //_sync_transactionsTables.ExitReadLock();
            }
        }
Example #19
0
        private void RestoreNotFinishedTransactions()
        {
            //TODO Trie settings from the table must be taken from schema (when they will differ)

            //STORE FILE NAME of rollback not table name
            try
            {
                byte[]        btCommittedTablesNames = null;
                List <string> committedTablesNames   = new List <string>();

                if (LTrie.Count(false) == 0)     //All ok
                {
                    LTrie.RemoveAll(true);
                    return;
                }

                string physicalPathToTheUserTable = String.Empty;

                //Settigns and storage for Committed tables !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!   MUST BE TAKEN FROM SCHEMA, FOR NOW DEFAULT
                TrieSettings            ltrSet  = null;
                IStorage                storage = null;
                DBriize.LianaTrie.LTrie ltrie   = null;


                foreach (var row in LTrie.IterateForward(true, false))
                {
                    btCommittedTablesNames = row.GetFullValue(true);

                    committedTablesNames = System.Text.Encoding.UTF8.GetString(btCommittedTablesNames).DeserializeXml <List <string> >();

                    foreach (var fn in committedTablesNames)
                    {
                        //Trying to get path from the Schema, there is universal function for getting table physical TABLE FULL PATH /NAME

                        physicalPathToTheUserTable = Engine.DBriizeSchema.GetPhysicalPathToTheUserTable(fn);

                        //Returned path can be empty, if no more such table
                        if (physicalPathToTheUserTable == String.Empty)
                        {
                            continue;
                        }

                        //We don't restore in-memory tables
                        if (physicalPathToTheUserTable == "MEMORY")
                        {
                            continue;
                        }

                        //we open ltrie, and it automatically restores rollback
                        ltrSet = new TrieSettings();     //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!   MUST BE TAKEN FROM SCHEMA, FOR NOW DEFAULT
                        //storage = new TrieDiskStorage(physicalPathToTheUserTable, ltrSet, Engine.Configuration);
                        storage = new StorageLayer(physicalPathToTheUserTable, ltrSet, Engine.Configuration);
                        ltrie   = new LTrie(storage);

                        //closing trie, that Schema could open it again
                        ltrie.Dispose();

                        ////Deleting rollback file for such table
                        //physicalPathToTheUserTable += ".rol";
                        //System.IO.File.Delete(physicalPathToTheUserTable);
                    }

                    committedTablesNames.Clear();
                }

                //If all ok, recreate file
                LTrie.RemoveAll(true);
            }
            catch (OperationCanceledException ex)
            {
                throw ex;
            }
            //catch (System.Threading.ThreadAbortException ex)
            //{
            //    //We don'T make DBisOperable = false;
            //    throw ex;
            //}
            catch (Exception)
            {
                //BRINGS TO DB NOT OPERATABLE
                this.Engine.DBisOperable       = false;
                this.Engine.DBisOperableReason = "TransactionsCoordinator.RestoreNotFinishedTransaction";
                //NOT CASCADE ADD EXCEPTION
                throw DBriizeException.Throw(DBriizeException.eDBriizeExceptions.CLEAN_ROLLBACK_FILES_FOR_FINISHED_TRANSACTIONS_FAILED);
            }
        }
Example #20
0
        //public OpenTable()
        //{
        //    Add();
        //}

        public OpenTable(LTrie trie)
        {
            this.Trie = trie;

            Add();
        }
Example #21
0
 internal Schema(LTrie trie, ulong lastFileNumber)
 {
     this.Trie           = trie;
     this.LastFileNumber = lastFileNumber;
 }
Example #22
0
        public static async Task AssertExists(this LTrie trie, string key)
        {
            using var result = await trie.GetValue("@utTestTa");

            Assert.NotNull(result);
        }
Example #23
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();
            }
        }
Example #24
0
 public async ValueTask <LTrie> ReloadTrie(LTrie trie)
 {
     var trie2 = await CreateTrie(trie.Storage, trie.NodeCache is { });