/// <summary> /// /// </summary> /// <param name="tableName"></param> /// <param name="key"></param> /// <param name="value"></param> public void Insert <TKey, TValue>(string tableName, TKey key, TValue value) { if (key == null) { throw new Exception("RandomKeySorter, key can't be null"); } byte[] btKey = DataTypesConvertor.ConvertKey <TKey>(key); byte[] btValue = DataTypesConvertor.ConvertKey <TValue>(value); var keyH = btKey.ToBytesString(); isUsed = true; if (!_cnt.ContainsKey(tableName)) { _cnt[tableName] = 0; } if (!_dInsert.ContainsKey(tableName)) { _dInsert[tableName] = new Dictionary <string, KeyValuePair <byte[], byte[]> >(); } _dInsert[tableName][keyH] = new KeyValuePair <byte[], byte[]>(btKey, btValue); _cnt[tableName]++; //Getting rid of Automatic flush, that makes inefficient TryGetValueByKey after flushing (will need always to check HD if not found in sorter) //if (_cnt[tableName] >= AutomaticFlushLimitQuantityPerTable) // Flush(tableName); }
/// <summary> /// Removes from the table key /// </summary> /// <typeparam name="TKey"></typeparam> /// <param name="tableName"></param> /// <param name="key"></param> public void Remove <TKey>(string tableName, TKey key) { if (key == null) { throw new Exception("RandomKeySorter, key can't be null"); } byte[] btKey = DataTypesConvertor.ConvertKey <TKey>(key); var keyH = btKey.ToBytesString(); isUsed = true; if (!_cnt.ContainsKey(tableName)) { _cnt[tableName] = 0; } if (!_dRemove.ContainsKey(tableName)) { _dRemove[tableName] = new Dictionary <string, byte[]>(); } _dRemove[tableName][keyH] = btKey; _cnt[tableName]++; if (_cnt[tableName] >= AutomaticFlushLimitQuantityPerTable) { Flush(tableName); } }
/// <summary> /// /// </summary> /// <param name="tableName"></param> /// <param name="key"></param> /// <param name="value"></param> public void Insert <TKey, TValue>(string tableName, TKey key, TValue value) { if (key == null) { throw new Exception("RandomKeySorter, key can't be null"); } byte[] btKey = DataTypesConvertor.ConvertKey <TKey>(key); byte[] btValue = DataTypesConvertor.ConvertKey <TValue>(value); var keyH = btKey.ToBytesString(); isUsed = true; if (!_cnt.ContainsKey(tableName)) { _cnt[tableName] = 0; } if (!_dInsert.ContainsKey(tableName)) { _dInsert[tableName] = new Dictionary <string, KeyValuePair <byte[], byte[]> >(); } _dInsert[tableName][keyH] = new KeyValuePair <byte[], byte[]>(btKey, btValue); _cnt[tableName]++; if (_cnt[tableName] >= AutomaticFlushLimitQuantityPerTable) { Flush(tableName); } }
/// <summary> /// Removes resource from database and /// </summary> public void Remove(string resourceName) { if (String.IsNullOrEmpty(resourceName)) { return; } string rn = _urp + resourceName; byte[] btKey = DataTypesConvertor.ConvertKey <string>(rn); _sync.EnterWriteLock(); try { _d.Remove(rn); LTrie.Remove(ref btKey); LTrie.Commit(); } catch (Exception ex) { throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.DBREEZE_RESOURCES_CONCERNING, "in Remove", ex); } finally { _sync.ExitWriteLock(); } }
/// <summary> /// Tries to grab from DBreeze first found node by supplied externalId /// or returns new DGNode (not yet saved to DB) with Node.Exists = false. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="externalId"></param> /// <param name="AsReadVisibilityScope"></param> /// <returns></returns> public DGNode GetNode <T>(T externalId, bool AsReadVisibilityScope = false) { DGNode node = null; byte[] btExId = DataTypesConvertor.ConvertKey <T>(externalId); if (externalId != null) { byte[] key = new byte[] { 1 }.Concat(btExId); foreach (var n in tran.SelectForwardStartFrom <byte[], byte[]>(tableName, key, false, AsReadVisibilityScope)) { if (!key.Substring(0, key.Length)._ByteArrayEquals(n.Key.Substring(0, key.Length))) { break; } else { node = new DGNode(btExId) { content = n.Value, graph = this, internalId = n.Key.Substring(key.Length).To_UInt32_BigEndian() }; break; } } } return(node ?? new DGNode(btExId) { graph = this }); }
/// <summary> /// Creates node (not yet saved to DB). Can be use node.Update, after node fill up. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="externalId"></param> /// <returns></returns> public DGNode NewNode <T>(T externalId) { var btExId = DataTypesConvertor.ConvertKey <T>(externalId); return(new DGNode(btExId) { graph = this }); }
/// <summary> /// SelectStartsWith. /// Value instance, when byte[], must stay immutable, please use Dbreeze.Utils.CloneArray /// </summary> /// <typeparam name="TValue"></typeparam> /// <param name="resourceNameStartsWith"></param> /// <param name="resourceSettings"></param> /// <returns></returns> public IEnumerable <KeyValuePair <string, TValue> > SelectStartsWith <TValue>(string resourceNameStartsWith, Settings resourceSettings = null) { if (!String.IsNullOrEmpty(resourceNameStartsWith)) { if (resourceSettings == null) { resourceSettings = _defaultSetting; } byte[] val = null; string rn = String.Empty; byte[] btKey = null; _sync.EnterUpgradeableReadLock(); btKey = DataTypesConvertor.ConvertKey <string>(_urp + resourceNameStartsWith); var q = LTrie.IterateForwardStartsWith(btKey, true, false); if (!resourceSettings.SortingAscending) { q = LTrie.IterateBackwardStartsWith(btKey, true, false); } foreach (var el in q) { rn = el.Key.UTF8_GetString(); if (!_d.TryGetValue(rn, out val)) { val = el.GetFullValue(false); if (resourceSettings.HoldInMemory) { _sync.EnterWriteLock(); try { _d[rn] = val; } catch (Exception) { } finally { _sync.ExitWriteLock(); } } } //no try..catch for yield return yield return(new KeyValuePair <string, TValue>(rn.Substring(1), val == null ? default(TValue) : DataTypesConvertor.ConvertBack <TValue>(val))); } _sync.ExitUpgradeableReadLock(); }//if is null or }
/// <summary> /// Removes from the table key /// </summary> /// <typeparam name="TKey"></typeparam> /// <param name="tableName"></param> /// <param name="key"></param> public void Remove <TKey>(string tableName, TKey key) { if (key == null) { throw new Exception("RandomKeySorter, key can't be null"); } byte[] btKey = DataTypesConvertor.ConvertKey <TKey>(key); var keyH = btKey.ToBytesString(); isUsed = true; if (!_cnt.ContainsKey(tableName)) { _cnt[tableName] = 0; } Dictionary <string, KeyValuePair <byte[], byte[]> > dInsertTable = null; if (_dInsert.TryGetValue(tableName, out dInsertTable)) { //Trying already to remove these values //NOTE if (dInsertTable.ContainsKey(keyH)) { dInsertTable.Remove(keyH); _cnt[tableName]--; if (!WasAutomaticallyFlushed) { return; //we can go out and don't put this to _remove list if in this session we entites were not flushed due to AutomaticFlushLimitQuantityPerTable, unless we must leave them in _dRemove table, so they are deleted when using Flush() } } } if (!_dRemove.ContainsKey(tableName)) { _dRemove[tableName] = new Dictionary <string, byte[]>(); } _dRemove[tableName][keyH] = btKey; _cnt[tableName]++; //Getting rid of Automatic flush, that makes inefficient TryGetValueByKey after flushing (will need always to check HD if not found in sorter) //if (_cnt[tableName] >= AutomaticFlushLimitQuantityPerTable) // Flush(tableName); }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="externalId"></param> /// <param name="AsReadVisibilityScope"></param> /// <returns></returns> public IEnumerable <DGNode> GetParent <T>(T externalId, bool AsReadVisibilityScope = false) { if (this.internalId == 0) //Not existing in DB node { yield return(null); } CheckGraph(); if (externalId == null) { throw new Exception("Searched ID can't be null"); } byte[] btExId = DataTypesConvertor.ConvertKey <T>(externalId); byte[] key = new byte[] { 4 }.ConcatMany(this.internalId.To_4_bytes_array_BigEndian(), btExId); byte[] key1 = null; DBreeze.DataTypes.Row <byte[], byte[]> row = null; DGNode node = null; foreach (var n in this.graph.tran.SelectForwardStartFrom <byte[], byte[]>(this.graph.tableName, key, false, AsReadVisibilityScope)) { //if (n.Key.Length <= 5) //1 - protocol + 4 bytes internalID //{ // break; //} //else if (!key.Substring(0, key.Length)._ByteArrayEquals(n.Key.Substring(0, key.Length))) { break; } else { node = new DGNode(btExId) { content = n.Value, graph = this.graph, internalId = n.Key.Substring(key.Length).To_UInt32_BigEndian() }; key1 = new byte[] { 1 }.ConcatMany(btExId, node.internalId.To_4_bytes_array_BigEndian()); row = this.graph.tran.Select <byte[], byte[]>(this.graph.tableName, key1, true); node.content = row.Value; yield return(node); } } }
/// <summary> /// Removes resources from database and In-Memory dictionary /// </summary> public void Remove(IList <string> resourcesNames) { if (resourcesNames == null || resourcesNames.Count == 0) { return; } byte[] btKey; string rn = String.Empty; _sync.EnterWriteLock(); try { foreach (var rs in resourcesNames) { if (String.IsNullOrEmpty(rs)) { continue; } rn = _urp + rs; _d.Remove(rn); btKey = DataTypesConvertor.ConvertKey <string>(rn); LTrie.Remove(ref btKey); } LTrie.Commit(); } catch (Exception ex) { throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.DBREEZE_RESOURCES_CONCERNING, "in Remove batch", ex); } finally { _sync.ExitWriteLock(); } }
/// <summary> /// Gets resource from memory or database (if not yet loaded) /// Value instance, when byte[], must stay immutable, please use Dbreeze.Utils.CloneArray /// </summary> /// <typeparam name="TValue"></typeparam> /// <param name="resourceName"></param> /// <param name="resourceSettings">resource extra behaviour</param> /// <returns></returns> public TValue Select <TValue>(string resourceName, Settings resourceSettings = null) { if (String.IsNullOrEmpty(resourceName)) { return(default(TValue)); } if (resourceSettings == null) { resourceSettings = _defaultSetting; } byte[] val = null; string rn = _urp + resourceName; _sync.EnterUpgradeableReadLock(); try { if (!_d.TryGetValue(rn, out val)) { //Value is not found _sync.EnterWriteLock(); try { //At this moment value appeared if (_d.TryGetValue(rn, out val)) { return(val == null ? default(TValue) : DataTypesConvertor.ConvertBack <TValue>(val)); } //trying to get from database byte[] btKey = DataTypesConvertor.ConvertKey <string>(rn); var row = LTrie.GetKey(btKey, false, false); if (row.Exists) { val = row.GetFullValue(false); if (val == null) { if (resourceSettings.HoldInMemory) { _d[rn] = null; } return(default(TValue)); } else { if (resourceSettings.HoldInMemory) { _d[rn] = val; } return(DataTypesConvertor.ConvertBack <TValue>(val)); } } else { if (resourceSettings.HoldInMemory) { _d[rn] = null; } return(default(TValue)); } } catch (Exception ex) { throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.DBREEZE_RESOURCES_CONCERNING, "in Select 1", ex); } finally { _sync.ExitWriteLock(); } } else { return(val == null ? default(TValue) : DataTypesConvertor.ConvertBack <TValue>(val)); } } catch (System.Exception ex) { throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.DBREEZE_RESOURCES_CONCERNING, "in Select 2", ex); } finally { _sync.ExitUpgradeableReadLock(); } }
/// <summary> /// Gets resources of the same type as a batch from memory or database (if not yet loaded). /// Value instance, when byte[], must stay immutable, please use Dbreeze.Utils.CloneArray /// </summary> /// <typeparam name="TValue"></typeparam> /// <param name="resourcesNames"></param> /// <param name="resourceSettings">resource extra behaviour</param> /// <returns></returns> public IDictionary <string, TValue> Select <TValue>(IList <string> resourcesNames, Settings resourceSettings = null) { Dictionary <string, TValue> ret = new Dictionary <string, TValue>(); if (resourcesNames == null || resourcesNames.Count < 1) { return(ret); } if (resourceSettings == null) { resourceSettings = _defaultSetting; } byte[] val = null; string rn = String.Empty; //bool ba = typeof(TValue) == typeof(byte[]); _sync.EnterUpgradeableReadLock(); try { foreach (var rsn in resourcesNames.OrderBy(r => r)) { if (String.IsNullOrEmpty(rsn)) { continue; } rn = _urp + rsn; if (!_d.TryGetValue(rn, out val)) { //Value is not found _sync.EnterWriteLock(); try { //At this moment value appeared if (_d.TryGetValue(rn, out val)) { if (val != null) { ret[rsn] = DataTypesConvertor.ConvertBack <TValue>(val); } else { ret[rsn] = default(TValue); } continue; } //trying to get from database byte[] btKey = DataTypesConvertor.ConvertKey <string>(rn); var row = LTrie.GetKey(btKey, false, false); if (row.Exists) { val = row.GetFullValue(false); if (val == null) { if (resourceSettings.HoldInMemory) { _d[rn] = null; } ret[rsn] = default(TValue); } else { if (resourceSettings.HoldInMemory) { _d[rn] = val; } ret[rsn] = DataTypesConvertor.ConvertBack <TValue>(val); } } else { if (resourceSettings.HoldInMemory) { _d[rn] = null; } ret[rsn] = default(TValue); } } catch (Exception ex) { throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.DBREEZE_RESOURCES_CONCERNING, "in Select 1", ex); } finally { _sync.ExitWriteLock(); } } else { if (val == null) { ret[rsn] = default(TValue); } else { ret[rsn] = DataTypesConvertor.ConvertBack <TValue>(val); } } }//eo foreach } catch (System.Exception ex) { throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.DBREEZE_RESOURCES_CONCERNING, "in Select 2", ex); } finally { _sync.ExitUpgradeableReadLock(); } return(ret); }
/// <summary> /// Batch insert of resources where value is a byte[] /// </summary> /// <param name="resources"></param> /// <param name="resourceSettings">resource extra behaviour</param> public void Insert(IDictionary <string, byte[]> resources, Settings resourceSettings = null) { if (resources == null || resources.Count < 1) { return; } if (resourceSettings == null) { resourceSettings = _defaultSetting; } byte[] btKey = null; byte[] btExVal = null; string rn = String.Empty; _sync.EnterWriteLock(); try { bool cov = LTrie.OverWriteIsAllowed; if (resourceSettings.HoldOnDisk && resourceSettings.FastUpdates) { LTrie.OverWriteIsAllowed = false; } foreach (var rs in resources.OrderBy(r => r.Key)) { if (String.IsNullOrEmpty(rs.Key)) { continue; } rn = _urp + rs.Key; //------- Verification, to prevent storing of the identical value if (resourceSettings.InsertWithVerification) { if (_d.TryGetValue(rn, out btExVal)) { if (btExVal._ByteArrayEquals(rs.Value)) { continue; } } else { //Grabbing from disk if (resourceSettings.HoldOnDisk) { var row = LTrie.GetKey(btKey, false, false); if (row.Exists) { btExVal = row.GetFullValue(false); if (btExVal._ByteArrayEquals(rs.Value)) { if (resourceSettings.HoldInMemory) { _d[rn] = rs.Value; } continue; } } } } } //------- if (resourceSettings.HoldInMemory) { _d[rn] = rs.Value; } if (resourceSettings.HoldOnDisk) { btKey = DataTypesConvertor.ConvertKey <string>(rn); LTrie.Add(btKey, rs.Value); } } if (resourceSettings.HoldOnDisk) { if (resourceSettings.FastUpdates) { LTrie.OverWriteIsAllowed = cov; } LTrie.Commit(); } } catch (Exception ex) { throw DBreezeException.Throw(DBreezeException.eDBreezeExceptions.DBREEZE_RESOURCES_CONCERNING, "in Insert batch", ex); } finally { _sync.ExitWriteLock(); } }
/// <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 }