/// <summary> /// Compacts the specified from buffer. /// </summary> /// <param name="fromBuffer">From buffer.</param> /// <param name="indexs">The indexes.</param> public static void Compact(ref InternalStorageBuffer fromBuffer, ref ConcurrentDictionary <string, BinaryStorageKey> indexs) { scrubBuffer.ResetBuffer(); foreach (var storageKey in indexs.Keys) { // Scrub out old data ;) BinaryStorageKey tmpKey; if (indexs.TryRemove(storageKey, out tmpKey)) { long pos = tmpKey.Position; int len = tmpKey.Length; var bytes = fromBuffer.FetchFromBuffer(pos, len); var idx = scrubBuffer.InsertSegment(bytes); tmpKey.Position = idx; indexs[storageKey] = tmpKey; } } // now copy over the data ;) fromBuffer.ResetBuffer(); scrubBuffer.TransferTo(ref fromBuffer); }
public void Add(string key, T objToAdd) { lock (_opsLock) { try { if (!_bufferIndexes.ContainsKey(key) && !_lstIndexes.ContainsKey(key)) { _itemCnt++; } byte[] data = objToAdd.ToByteArray(); // we need to add to buffer first ;) if (_internalBuffer.CanFitSegment(data.Length)) { // shove into the internal buffer ;) var bufferIdx = _internalBuffer.InsertSegment(data); _bufferIndexes[key] = new BinaryStorageKey { Length = data.Length, Position = bufferIdx }; } else { // dump the buffer to file ;) MoveBufferToFile(); // once buffer is dumped, check for compaction operation ;) // TODO : Background operation so we can continue to fill buffer ;) if (_file.Length - _lastCompactSize > CompactThresholdSize) { Compact(); } if (_internalBuffer.CanFitSegment(data.Length)) { // shove into the internal buffer ;) var bufferIdx = _internalBuffer.InsertSegment(data); _bufferIndexes[key] = new BinaryStorageKey { Length = data.Length, Position = bufferIdx }; } else { // Too big, dump to file directly ;) BinaryStorageKey tmp; if (_lstIndexes.TryGetValue(key, out tmp)) { tmp.Length = data.Length; tmp.Position = _file.Length; _lstIndexes[key] = tmp; } else { tmp = new BinaryStorageKey { Length = data.Length, Position = _file.Length }; _lstIndexes.TryAdd(key, tmp); } _file.Seek(_file.Length, SeekOrigin.Begin); _file.Write(data, 0, data.Length); } } } catch (Exception e) { Dev2Logger.Log.Error(e); } } }