/// <summary> /// Renames user table, if it existed. /// <para>If there are threads which are working with this table, rename will not be finished and will return false</para> /// </summary> /// <param name="oldUserTableName"></param> /// <param name="newUserTableName"></param> /// <returns>true if successfully renamed, otherwise false</returns> private bool RenameTableInternal(string oldUserTableName, string newUserTableName) { this.DeleteTable(newUserTableName); _sync_openTablesHolder.EnterWriteLock(); try { string oldTableName = GetUserTableNameAsString(oldUserTableName); string newTableName = GetUserTableNameAsString(newUserTableName); OpenTable ot = null; string alternativeTableLocation = String.Empty; bool inMemory = false; _openTablesHolder.TryGetValue(oldTableName, out ot); if (CheckAlternativeTableLocationsIntersections(oldUserTableName, out alternativeTableLocation)) { if (alternativeTableLocation == String.Empty) { //In-Memory Table inMemory = true; } else { if (ot != null) { return(false); //Other threads are working with this table } } } else { if (Engine.Configuration.Storage == DBreezeConfiguration.eStorage.MEMORY) { //In-Memory Table inMemory = true; } else { if (ot != null) { return(false); //Other threads are working with this table } } } //Changing key in Schema db byte[] btOldTableName = GetUserTableNameAsByte(oldUserTableName); byte[] btNewTableName = GetUserTableNameAsByte(newUserTableName); LTrie.ChangeKey(ref btOldTableName, ref btNewTableName); LTrie.Commit(); this.cachedTableNames.Remove(oldTableName); if (inMemory && ot != null) { //Changing reference for in-memory table, _openTablesHolder.Add(newTableName, ot); _openTablesHolder.Remove(oldTableName); } } catch (System.Exception ex) { DBreezeException.Throw(DBreezeException.eDBreezeExceptions.SCHEME_TABLE_RENAME_FAILED, oldUserTableName, ex); } finally { _sync_openTablesHolder.ExitWriteLock(); } return(true); }
/// <summary> /// Called by Transaction, when it's time to be Disposed and close tables. /// Tables will be closed only in case of other threads don't use it. /// </summary> /// <param name="closeOpenTables"></param> internal void CloseTables(Dictionary <string, ulong?> closeOpenTables) { //if (Engine.Configuration.Storage == DBreezeConfiguration.eStorage.MEMORY) // return; string tableName = String.Empty; OpenTable ot = null; bool toClose = false; string alternativeTableLocation = String.Empty; _sync_openTablesHolder.EnterWriteLock(); try { //utn - user table name foreach (var utn in closeOpenTables) { if (CheckAlternativeTableLocationsIntersections(utn.Key, out alternativeTableLocation)) { if (alternativeTableLocation == String.Empty) { //Memory table, we don't close continue; } else { //Physical table...going on } } else { //Table location is not overridden, working further based on main DBreeze configuration if (Engine.Configuration.Storage == DBreezeConfiguration.eStorage.MEMORY) { continue; //we don't close memory tables } } tableName = GetUserTableNameAsString(utn.Key); _openTablesHolder.TryGetValue(tableName, out ot); if (ot != null) { toClose = ot.Remove((ulong)utn.Value); if (AutoCloseOpenTables) //If AutoCloseIsEnabled, we dispose LTrie and closing physical file. { if (toClose) { //Closing table //Console.WriteLine("Closing: " + utn.Key); ot.Dispose(); _openTablesHolder.Remove(tableName); } } } //else //{ //} } } finally { _sync_openTablesHolder.ExitWriteLock(); } }
public Table() { Open = new OpenTable <TRow, TColumn, TValue>(this); Existed = new ExistedTable <TRow, TColumn, TValue>(this); }
/// <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(); } }
public Task OpenTable(OpenTable cmd) { return(null); }