/// <summary> /// Add tables and their InternalDocumentIDs for paraller indexing /// </summary> /// <param name="defferedDocIds"></param> public void Add(Dictionary <string, HashSet <uint> > defferedDocIds) { if (defferedDocIds == null || defferedDocIds.Count == 0) { return; } lock (lock_operation) { init++; var bt = DBreeze.Utils.Biser.Encode_DICT_PROTO_STRING_UINTHASHSET(defferedDocIds, Compression.eCompressionMethod.NoCompression); LTrie.Add(init.To_8_bytes_array_BigEndian(), bt); LTrie.Commit(); } }
/// <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 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(); } }
internal void Commit() { table.Commit(); }
/// <summary> /// Insert resource /// </summary> /// <typeparam name="TValue"></typeparam> /// <param name="resourceName"></param> /// <param name="resourceObject"></param> /// <param name="resourceSettings">resource extra behaviour</param> public void Insert <TValue>(string resourceName, TValue resourceObject, Settings resourceSettings = null) { if (String.IsNullOrEmpty(resourceName)) { return; } if (resourceSettings == null) { resourceSettings = _defaultSetting; } string rn = _urp + resourceName; byte[] btKey = DataTypesConvertor.ConvertKey <string>(rn); byte[] btValue = DataTypesConvertor.ConvertValue <TValue>(resourceObject); _sync.EnterWriteLock(); try { //------- Verification, to prevent storing of the identical value if (resourceSettings.InsertWithVerification) { byte[] btExVal = null; if (_d.TryGetValue(rn, out btExVal)) { if (btExVal._ByteArrayEquals(btValue)) { return; } } else { //Grabbing from disk if (resourceSettings.HoldOnDisk) { var row = LTrie.GetKey(btKey, false, false); if (row.Exists) { btExVal = row.GetFullValue(false); if (btExVal._ByteArrayEquals(btValue)) { if (resourceSettings.HoldInMemory) { _d[rn] = btValue; } return; } } } } } //------- if (resourceSettings.HoldOnDisk) { bool cov = LTrie.OverWriteIsAllowed; if (resourceSettings.FastUpdates) { LTrie.OverWriteIsAllowed = false; } LTrie.Add(btKey, btValue); LTrie.Commit(); if (resourceSettings.FastUpdates) { LTrie.OverWriteIsAllowed = cov; } } if (resourceSettings.HoldInMemory) { _d[rn] = btValue; } } catch (Exception ex) { throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.DBREEZE_RESOURCES_CONCERNING, "in Insert", ex); } finally { _sync.ExitWriteLock(); } #region "remark" // if (holdInMemory) // { // _sync.EnterWriteLock(); // try // { // _d[resourceName] = btValue; // } // catch (Exception ex) // { // throw ex; // } // finally // { // _sync.ExitWriteLock(); // } // } // Action a = () => // { // _sync.EnterWriteLock(); // try // { // LTrie.Add(btKey, btValue); // LTrie.Commit(); // } // catch (Exception ex) // { // throw ex; // } // finally // { // _sync.ExitWriteLock(); // } // }; //#if NET35 || NETr40 //The same must be use for .NET 4.0 // new System.Threading.Thread(new System.Threading.ThreadStart(() => // { // a(); // })).Start(); //#else // System.Threading.Tasks.Task.Run(() => { // a(); // }); //#endif #endregion }