/// <summary> /// Closes the storage and clears memory used by the instance /// </summary> public void Dispose() { if (_disposed) { return; } try { bool locked = false; try { if (!IsReadOnly) { locked = _selfLock.TryWrite(Math.Max(1000, LockTimeout)); if (locked) { CommitChanges(false); } } _storage.Dispose(); } finally { try { if (_options.LogFile != null) { _options.LogFile.Dispose(); } } finally { if (locked) { _selfLock.ReleaseWrite(); } //Do not dispose, this may be a shared lock: //_selfLock.Dispose(); } } } finally { _disposed = true; } }
public BPlusTree(BPlusTreeOptions <TKey, TValue> ioptions) { bool fileExists = ioptions.StorageType == StorageType.Disk && ioptions.CreateFile != CreatePolicy.Always && File.Exists(ioptions.FileName) && new FileInfo(ioptions.FileName).Length > 0; _options = ioptions.Clone(); _selfLock = _options.CallLevelLock; _keyComparer = _options.KeyComparer; _itemComparer = new ElementComparer(_keyComparer); switch (_options.CachePolicy) { case CachePolicy.All: _storage = new NodeCacheFull(_options); break; case CachePolicy.Recent: _storage = new NodeCacheNormal(_options); break; case CachePolicy.None: _storage = new NodeCacheNone(_options); break; default: throw new InvalidConfigurationValueException("CachePolicy"); } try { _storage.Load(); } catch { _storage.Dispose(); throw; } if (_options.LogFile != null && !_options.ReadOnly) { if (_options.ExistingLogAction == ExistingLogAction.Truncate || _options.ExistingLogAction == ExistingLogAction.Default && !fileExists) { _options.LogFile.TruncateLog(); } else if (_options.LogFile.Size > 0 && ( _options.ExistingLogAction == ExistingLogAction.Replay || _options.ExistingLogAction == ExistingLogAction.ReplayAndCommit || (_options.ExistingLogAction == ExistingLogAction.Default && fileExists) )) { bool commit = (_options.ExistingLogAction == ExistingLogAction.ReplayAndCommit || (_options.ExistingLogAction == ExistingLogAction.Default && fileExists)); bool merge = false; if (_options.StorageType == StorageType.Disk) { merge = new FileInfo(_options.FileName).Length < _options.LogFile.Size; } if (merge) // log data is larger than we are... { BulkInsertOptions opts = new BulkInsertOptions(); opts.CommitOnCompletion = commit; opts.DuplicateHandling = DuplicateHandling.LastValueWins; opts.InputIsSorted = true; opts.ReplaceContents = true; BulkInsert( _options.LogFile.MergeLog(_options.KeyComparer, File.Exists(ioptions.FileName) ? EnumerateFile(ioptions) : new KeyValuePair <TKey, TValue> [0]), opts ); } else { _options.LogFile.ReplayLog(this); if (commit) //Now commit the recovered changes { Commit(); } } } } var nodeStoreWithCount = _storage.Storage as INodeStoreWithCount; if (nodeStoreWithCount != null) { _count = nodeStoreWithCount.Count; _hasCount = _count >= 0; } }