/// <summary> /// 关闭 /// </summary> public void Shutdown() { lock (_shutdownlock) { if (_index != null) { log.Debug("Shutting down"); } else { return; } _savetimer.Enabled = false; SaveIndex(); SaveLastRecord(); if (_deleted != null) { _deleted.Shutdown(); } if (_index != null) { _index.Shutdown(); } if (_archive != null) { _archive.Shutdown(); } _index = null; _archive = null; _deleted = null; //log.Debug("Shutting down log"); //LogManager.Shutdown(); } }
public void CompactStorageHF() { lock (_lock) { try { _log.Debug("Compacting storage file ..."); if (Directory.Exists(_Path + "temp")) { Directory.Delete(_Path + "temp", true); } KeyStoreHF newfile = new KeyStoreHF(_Path + "temp"); string[] keys = _keys.GetKeys().Cast <string>().ToArray(); _log.Debug("Number of keys : " + keys.Length); foreach (var k in keys) { newfile.SetObjectHF(k, GetObjectHF(k)); } newfile.Shutdown(); _log.Debug("Compact done."); // shutdown and move files and restart here if (Directory.Exists(_Path + "old")) { Directory.Delete(_Path + "old", true); } Directory.CreateDirectory(_Path + "old"); _datastore.Shutdown(); _keys.Shutdown(); _log.Debug("Moving files..."); foreach (var f in Directory.GetFiles(_Path, "*.*")) { File.Move(f, _Path + "old" + _S + Path.GetFileName(f)); } foreach (var f in Directory.GetFiles(_Path + "temp", "*.*")) { File.Move(f, _Path + Path.GetFileName(f)); } Directory.Delete(_Path + "temp", true); //Directory.Delete(_Path + "old", true); // FEATURE : delete or keep? _log.Debug("Re-opening storage file"); _datastore = new StorageFileHF(Path.Combine(_Path, "data.mghf"), Global.HighFrequencyKVDiskBlockSize); _keys = new MGIndex <string>(_Path, "keys.idx", 255, /*Global.PageItemCount,*/ false); _BlockSize = _datastore.GetBlockSize(); } catch (Exception ex) { _log.Error(ex); } } }
public KeyStoreHF(string folder) { _Path = folder; Directory.CreateDirectory(_Path); if (_Path.EndsWith(_S) == false) { _Path += _S; } if (File.Exists(_Path + _dirtyFilename)) { _log.Error("Last shutdown failed, rebuilding data files..."); RebuildDataFiles(); } _datastore = new StorageFileHF(Path.Combine(_Path, "data.mghf"), Global.HighFrequencyKVDiskBlockSize); _keys = new MGIndex <string>(_Path, "keys.idx", 255, /*Global.PageItemCount,*/ false); _datastore.Initialize(); _BlockSize = _datastore.GetBlockSize(); }
/// <summary> /// 初始化 /// </summary> /// <param name="filename"></param> /// <param name="maxkeysize"></param> /// <param name="AllowDuplicateKeys"></param> private void Initialize(string filename, byte maxkeysize, bool AllowDuplicateKeys) { _MaxKeySize = RDBDataType <T> .GetByteSize(maxkeysize); _T = RDBDataType <T> .ByteHandler(); _Path = Path.GetDirectoryName(filename); Directory.CreateDirectory(_Path); _FileName = Path.GetFileNameWithoutExtension(filename); string db = Path.Combine(_Path, _FileName + _datExtension); _index = new MGIndex <T>(_Path, _FileName + _idxExtension, _MaxKeySize, AllowDuplicateKeys); if (Global.SaveAsBinaryJSON) { _archive = new StorageFile <T>(db, SF_FORMAT.BSON, false); } else { _archive = new StorageFile <T>(db, SF_FORMAT.JSON, false); } _deleted = new BoolIndex(_Path, _FileName); log.Debug("Current Count = " + RecordCount().ToString("#,0")); CheckIndexState(); //保存服务 log.Debug("Starting save timer"); _savetimer = new System.Timers.Timer(); _savetimer.Elapsed += new System.Timers.ElapsedEventHandler(_savetimer_Elapsed); _savetimer.Interval = Global.SaveIndexToDiskTimerSeconds * 1000; _savetimer.AutoReset = true; _savetimer.Start(); }
private void RebuildDataFiles() { MGIndex <string> keys = null; try { // remove old free list if (File.Exists(_Path + "data.bmp")) { File.Delete(_Path + "data.bmp"); } _datastore = new StorageFileHF(Path.Combine(_Path, "data.mghf"), Global.HighFrequencyKVDiskBlockSize); _BlockSize = _datastore.GetBlockSize(); if (File.Exists(_Path + "keys.idx")) { _log.Debug("removing old keys index"); foreach (var f in Directory.GetFiles(_Path, "keys.*")) { File.Delete(f); } } keys = new MGIndex <string>(_Path, "keys.idx", 255, /*Global.PageItemCount,*/ false); WAHBitArray visited = new WAHBitArray(); int c = _datastore.NumberofBlocks(); for (int i = 0; i < c; i++) // go through blocks { if (visited.Get(i)) { continue; } byte[] b = _datastore.ReadBlockBytes(i, _blockheader.Length + 255); int bnum = Helper.ToInt32(b, 0); if (bnum > 0) // check if a start block { visited.Set(i, true); _datastore.FreeBlock(i); // mark as free continue; } AllocationBlock ab = new AllocationBlock(); // start block found int blocknumexpected = 0; int next = ParseBlockHeader(ab, b, blocknumexpected); int last = 0; bool freelast = false; AllocationBlock old = null; if (keys.Get(ab.key, out last)) { old = this.FillAllocationBlock(last); freelast = true; } blocknumexpected++; bool failed = false; if (ab.deleteKey == false) { while (next > 0) // read the blocks { ab.Blocks.Add(next); b = _datastore.ReadBlockBytes(next, _blockheader.Length + ab.keylen); next = ParseBlockHeader(ab, b, blocknumexpected); if (next == -1) // non matching block { failed = true; break; } blocknumexpected++; } } else { failed = true; keys.RemoveKey(ab.key); } // new data ok if (failed == false) { keys.Set(ab.key, ab.blocknumber); // valid block found if (freelast) // free the old blocks { _datastore.FreeBlocks(old.Blocks); } } visited.Set(i, true); } // all ok delete temp.$ file if (File.Exists(_Path + _dirtyFilename)) { File.Delete(_Path + _dirtyFilename); } } catch (Exception ex) { _log.Error(ex); } finally { _log.Debug("Shutting down files and index"); _datastore.Shutdown(); keys.SaveIndex(); keys.Shutdown(); } }