public void Remove(Transaction.ITransactionLogger transaction) { if (Count == 0) { return; } var keys = new List <object>(); foreach (MruItem itm in CacheCollection.Values) { if (itm.Transaction == transaction) { keys.Add(itm.Key); } } foreach (object o in keys) { var m = (MruItem)CacheCollection[o]; if (m != null && m.IndexToMruList != null) { mruManager.RemoveNode(m.IndexToMruList, true); } CacheCollection.Remove(o); } }
public MruItem(object key, object value, Transaction.ITransactionLogger transaction) { this.Key = key; this.Value = value; this._transaction = transaction; }
public void Remove(Transaction.ITransactionLogger transaction) { if (Count == 0) { return; } var keys = new List <TKey>(); foreach (MruItem <TKey, TValue> itm in CacheCollection.Values) { if (itm.Transaction == transaction) { keys.Add(itm.Key); } } foreach (TKey o in keys) { MruItem <TKey, TValue> m = CacheCollection[o]; if (m != null && m.IndexToMruList != null) { mruManager.RemoveNode(m.IndexToMruList); } CacheCollection.Remove(o); } }
private void AllocateOnNextSegment(CollectionOnDisk parent, HeaderData hd, Sop.DataBlock block) { long g; long segmentSize = parent.Grow(out g); if (segmentSize > 0) { Transaction.ITransactionLogger trans = parent.Transaction; if (trans != null) { ((Transaction.TransactionBase)trans).RegisterFileGrowth(parent, g, segmentSize); } } else { string s = string.Format("File '{0}' failed to grow.", parent.File.Filename); //_logger.LogLine(s); throw new InvalidOperationException(s); } hd.OnDiskLeftoverSegmentSize = (int)(hd.EndAllocatableAddress - hd.NextAllocatableAddress); hd.StartAllocatableAddress = g; hd.EndAllocatableAddress = hd.StartAllocatableAddress + segmentSize; hd.NextAllocatableAddress = hd.StartAllocatableAddress; block.DataAddress = hd.NextAllocatableAddress; hd.NextAllocatableAddress += block.Length; hd.DiskBuffer.IsDirty = true; hd.IsModifiedInTransaction = true; }
/// <summary> /// Remove from in-memory blocks the block referenced /// by DataAddress. /// NOTE: this function is invoked when Rolling back changes /// </summary> /// <param name="dataAddress"></param> /// <param name="transaction"> </param> internal virtual bool RemoveInMemory(long dataAddress, Transaction.ITransactionLogger transaction) { //** current block if (currentDataBlock != null && (currentDataBlock.DataAddress == -1 || currentDataBlock.IsBlockOfThis(dataAddress))) { currentEntry = currentDataBlock = null; _currentEntryDataAddress = -1; } //** MRU RemoveFromCache(transaction); if (DataBlockDriver.HeaderData.RecycledSegment != null) { if (dataAddress >= DataBlockDriver.HeaderData.RecycledSegment.StartBlockAddress && dataAddress <= (DataBlockDriver.HeaderData.RecycledSegment.StartBlockAddress + DataBlockDriver.HeaderData.RecycledSegment.Count * (int)DataBlockSize)) { DataBlockDriver.HeaderData.RecycledSegment = null; } } //** take care of deleted blocks list... if (deletedBlocks is CollectionOnDisk) { ((CollectionOnDisk)deletedBlocks).RemoveInMemory(dataAddress, transaction); } //** Header and DiskBuffer return(DiskBuffer.DataAddress == -1 || DiskBuffer.IsBlockOfThis(dataAddress) || HeaderData.DiskBuffer.DataAddress == -1 || HeaderData.DiskBuffer.IsBlockOfThis(dataAddress)); }
/// <summary> /// protected virtual dispose. /// Closes this Collection on disk, its deleted blocks and Mru Segments. /// Sets the data block driver to null. /// </summary> protected internal virtual void InternalDispose() { if (FileStream != null) { Close(); } if (deletedBlocks != null) { deletedBlocks.Dispose(); deletedBlocks = null; } Parent = null; if (DataBlockDriver != null) { if (!IsCloned) { DataBlockDriver.Dispose(); } DataBlockDriver = null; } if (OnDiskBinaryReader != null) { OnDiskBinaryReader.Close(); OnDiskBinaryReader = null; } if (OnDiskBinaryWriter != null) { OnDiskBinaryWriter.Close(); OnDiskBinaryWriter = null; } _instanceTransaction = null; _parentTransactionLogger = null; File = null; }
public MruItem(TKey key, TValue value, Transaction.ITransactionLogger transaction) { this.Key = key; this.Value = value; this._transaction = transaction; }
/// <summary> /// protected virtual dispose. /// Closes this Collection on disk, its deleted blocks and Mru Segments. /// Sets the data block driver to null. /// </summary> protected internal virtual void InternalDispose() { // note: SOP's Dispose pattern is created to provide way to do early // garbage collection of the "graph" objects, simply. Not for freeing up unmanaged // resources, thus, no finalizer/SafeHandle "patterns". All members are "virtualized" // objects and they have custom Dispose for the same. if (isDisposed) { return; } isDisposed = true; // FileStream is a wrapper, not the .Net FileStream. if (FileStream != null) { Close(); } if (deletedBlocks != null) { deletedBlocks.Dispose(); deletedBlocks = null; } Parent = null; if (DataBlockDriver != null) { //if (!IsCloned) DataBlockDriver.Dispose(); DataBlockDriver = null; } if (OnDiskBinaryReader != null) { OnDiskBinaryReader.Close(); OnDiskBinaryReader = null; } if (OnDiskBinaryWriter != null) { OnDiskBinaryWriter.Close(); OnDiskBinaryWriter = null; } _instanceTransaction = null; _parentTransactionLogger = null; File = null; Blocks = null; var locker = _syncRoot as IDisposable; if (locker != null) { locker.Dispose(); } }
private void AllocateAvailableBlock(CollectionOnDisk parent, HeaderData hd, Sop.DataBlock block) { //** Allocate block from the "available" segment block.DataAddress = hd.NextAllocatableAddress; hd.NextAllocatableAddress += block.Length; hd.DiskBuffer.IsDirty = true; hd.IsModifiedInTransaction = true; //** register the add of new block to transaction log Transaction.ITransactionLogger trans = parent.Transaction; if (trans == null) { return; } ((Transaction.TransactionBase)trans).RegisterAdd(parent, block.DataAddress, block.Length); }
/// <summary> /// Remove the File with a given Name from the Set and optionally /// delete it from the file system /// </summary> /// <param name="name"></param> /// <param name="deleteFile"></param> private bool Remove(string name, bool deleteFile) { if (this.Btree.File.Server.ReadOnly) { throw new InvalidOperationException("Object Server is in read only mode."); } if (!deleteFile) { Locker.Invoke(() => { Btree.Remove(name); }); return(true); } //** todo: optimize to not open File as isn't needed... return(Locker.Invoke(() => { IFile f = this[name]; Btree.Remove(name); if (f != null) { string filename = f.Filename; Transaction.ITransactionLogger trans = null; if (f.Server != null) { trans = (Transaction.ITransactionLogger)f.Server.Transaction; } f.Dispose(); if (trans != null) { ((Transaction.TransactionRoot)trans.Root).RegisterRemoveFile(filename); } try { System.IO.File.Delete(filename); } catch { if (trans != null) { ((Transaction.TransactionRoot)trans.Root).RegisterFailure( Sop.Transaction.TransactionRootFailTypes.RemoveFileFailure, filename); } throw; } return true; } return false; })); }
/// <summary> /// Given a key, will return its value. /// If key is not found, will add a new entry having passed /// params key and value. /// </summary> public object this[object key] { get { // check if item is in removed objects, not likely but in case... if (mruManager.RemovedObjects.Count > 0 && mruManager.RemovedObjects.ContainsKey(key)) { return(mruManager.RemovedObjects.CurrentValue); } MruItem itm = (MruItem)this.CacheCollection[key]; if (itm == null) { return(null); } if ((SaveState & SaveTypes.CollectionSave) != SaveTypes.CollectionSave) { if (itm.IndexToMruList != null) { mruManager.RemoveNode(itm.IndexToMruList, true); mruManager.AddInHead(itm.IndexToMruList, true); } } return(itm.Value); } set { if ((SaveState & SaveTypes.CollectionSave) == SaveTypes.CollectionSave) { return; } MruItem itm = (MruItem)this.CacheCollection[key]; if (itm != null) { itm.Transaction = ((OnDisk.Algorithm.Collection.ICollectionOnDisk) this.mruManager.Collection).Transaction; mruManager.RemoveNode(itm.IndexToMruList, true); itm.Value = value; mruManager.AddInHead(itm.IndexToMruList, true); } else { Transaction = ((OnDisk.Algorithm.Collection.ICollectionOnDisk) this.mruManager.Collection).Transaction; this.Add(key, value); } } }
/// <summary> /// Given a key, will return its value. /// If key is not found, will add a new entry having passed /// params key and value. /// </summary> public TValue this[TKey key] { get { MruItem <TKey, TValue> itm = this.CacheCollection[key]; if (itm == null) { return(default(TValue)); } if ((SaveState & Sop.Mru.SaveTypes.CollectionSave) != Sop.Mru.SaveTypes.CollectionSave) { if (itm.IndexToMruList != null) { mruManager.RemoveNode(itm.IndexToMruList); mruManager.AddInHead(itm.IndexToMruList, true); } } return(itm.Value); } set { if ((SaveState & Sop.Mru.SaveTypes.CollectionSave) == Sop.Mru.SaveTypes.CollectionSave) { return; } MruItem <TKey, TValue> itm = this.CacheCollection[key]; if (itm != null) { itm.Transaction = ((OnDisk.Algorithm.Collection.ICollectionOnDisk) this.mruManager.Collection).Transaction; mruManager.RemoveNode(itm.IndexToMruList); itm.Value = value; mruManager.AddInHead(itm.IndexToMruList, true); } else { Transaction = ((OnDisk.Algorithm.Collection.ICollectionOnDisk) this.mruManager.Collection).Transaction; this.Add(key, value); } } }
/// <summary> /// Remove the Object with "Address" from Object and Sop.DataBlock MRUs. /// </summary> /// <param name="transaction"> </param> public virtual void RemoveFromCache(Transaction.ITransactionLogger transaction) { //if (MruManager != null) // MruManager.Remove(transaction); //DataBlockDriver.MruManager.Remove(transaction); }
private DeletedBlockInfo RecycleBlock(Algorithm.Collection.ICollectionOnDisk parent, Sop.DataBlock block, bool isCollectionBlock, out int totalBlockSize, out bool fromCollection) { int blockLength = block.Length; totalBlockSize = block.CountMembers() * blockLength; var dbi = ((CollectionOnDisk)parent).GetDeletedBlock(totalBlockSize, isCollectionBlock, out fromCollection); if (dbi == null) { totalBlockSize = -1; return(dbi); } if (!fromCollection) { return(dbi); } if (dbi.IsContiguousBlock) { #region NOT VISITED BLOCK //** from Collection.DeletedBlocks (IsContiguousBlock = true) if (dbi.Count * (int)parent.DataBlockSize < totalBlockSize) { string errMsg = "RecycleBlock: Total Requested Block Size > recycled Deleted Block(s)."; Log.Logger.Instance.Log(Log.LogLevels.Fatal, errMsg); throw new InvalidOperationException(errMsg); } #endregion // Register recycled blocks so they can get handled properly, e.g. - will not get backed up during Store Flush. if (parent.Transaction != null) { ((Transaction.TransactionBase)parent.Transaction).Register( Sop.Transaction.ActionType.Recycle, (CollectionOnDisk)parent, dbi.StartBlockAddress, dbi.Count * blockLength); } // set Block to the block addresses referenced in dbi int count = dbi.Count; long address = dbi.StartBlockAddress; Sop.DataBlock db = block; Transaction.ITransactionLogger trans = parent.Transaction; Sop.DataBlock dbPrev = null; while (db != null) { dbi.Count--; db.DataAddress = address; if (dbPrev != null) { dbPrev.NextItemAddress = address; dbPrev.Next = db; SetIsDirty(dbPrev, true); } address += blockLength; dbPrev = db; db = db.Next; } SetIsDirty(dbPrev, true); var codParent = (CollectionOnDisk)parent; IDataBlockRecycler delBlocks = codParent.DeletedBlocks; if (HeaderData.RecycledSegment != dbi || HeaderData.RecycledSegment == null) { if (delBlocks != null) { delBlocks.RemoveAvailableBlock(dbi.StartBlockAddress); } } if (dbi.Count == 0) { dbi.Count = count; HeaderData.RecycledSegment = null; } else { HeaderData.RecycledSegment = (DeletedBlockInfo)dbi.Clone(); HeaderData.RecycledSegment.StartBlockAddress = address; dbi.Count = count; } } return(dbi); }
public virtual bool RemoveInMemory(long dataAddress, Transaction.ITransactionLogger transaction) { return(RealDictionary.RemoveInMemory(dataAddress, transaction)); }
/// <summary> /// Create Instance /// </summary> /// <param name="transaction"> </param> /// <param name="typeId"></param> /// <param name="parameters"></param> /// <returns></returns> public object CreateInstance(Transaction.ITransactionLogger transaction, byte typeId, params KeyValuePair <string, object>[] parameters) { if (typeId >= (byte)BuiltinTypes.MinType && typeId <= (byte)BuiltinTypes.MaxType) { File.File f; switch ((BuiltinTypes)typeId) { case BuiltinTypes.SortedDictionaryOnDisk: f = (File.File)CollectionOnDisk.GetParamValue(parameters, "File"); if (f != null) { if (transaction is Sop.Transaction.TransactionBase) { return(((Sop.Transaction.TransactionBase)transaction).CreateCollection(f)); } else { return(new SortedDictionaryOnDisk(f)); } } return(transaction is Sop.Transaction.TransactionBase ? ((Sop.Transaction.TransactionBase)transaction).CreateCollection(f) : new SortedDictionaryOnDisk()); case BuiltinTypes.SharedBlockOnDiskList: f = (File.File)CollectionOnDisk.GetParamValue(parameters, "File"); if (f != null) { return(new SharedBlockOnDiskList(f)); } return(new SharedBlockOnDiskList()); case BuiltinTypes.BTreeAlgorithm: return(new BTreeAlgorithm()); case BuiltinTypes.File: return(transaction is Sop.Transaction.TransactionBase ? ((Sop.Transaction.TransactionBase)transaction).CreateFile() : new File.File()); case BuiltinTypes.FileSet: return(transaction is Sop.Transaction.TransactionBase ? ((Sop.Transaction.TransactionBase)transaction).CreateFileSet() : new FileSet()); case BuiltinTypes.LinkedListOnDisk: return(new LinkedListOnDisk()); case BuiltinTypes.LinkedListOnDiskItemOnDisk: return(new LinkedListOnDisk.LinkedItemOnDisk()); case BuiltinTypes.BTreeOnDiskTreeNode: return(new BTreeNodeOnDisk()); case BuiltinTypes.BTreeItemOnDisk: return(new ItemOnDisk()); case BuiltinTypes.DeletedBlockInfo: return(new DeletedBlockInfo()); case BuiltinTypes.DataReference: return(new DataReference()); case BuiltinTypes.BackupDataLogKey: return(new Transaction.Transaction.BackupDataLogKey()); case BuiltinTypes.BackupDataLogValue: return(new Transaction.Transaction.BackupDataLogValue()); case BuiltinTypes.UserDefined: return(null); default: throw new ArgumentOutOfRangeException("typeId", typeId, "Not supported Type ID."); } } //** TypeID should be a User type... throw new InvalidOperationException( string.Format("Built-in TypeStore doesn't support this Type ID '{0}'.", typeId) ); }
/// <summary> /// Initialize. NOTE: this function doesn't open the file. /// </summary> /// <param name="file"></param> /// <param name="parameters"> </param> protected internal virtual void Initialize(File.IFile file, params KeyValuePair <string, object>[] parameters) { if (file == null) { throw new ArgumentNullException("file"); } if (transaction == null || (transaction is Transaction.Transaction && ((Transaction.Transaction)transaction).Server != file.Server)) { Transaction.ITransactionLogger trans = file.Transaction; if (trans != null) { trans = ((Transaction.TransactionBase)trans).GetLeafChild(); } if (trans == null || trans is Transaction.Transaction) { transaction = trans; } } if (string.IsNullOrEmpty(this.Name)) { var f = new FileInfo(file.Filename); Name = string.Format("{0} Collection {1}", f.Name, ((Sop.OnDisk.File.File)file).GetNewStoreId()); } if (MruMinCapacity == 0) { MruMinCapacity = file.Profile.MruMinCapacity; } if (MruMaxCapacity == 0) { MruMaxCapacity = file.Profile.MruMaxCapacity; } if (File == null) { File = file; } if (DataBlockSize == DataBlockSize.Unknown) { DataBlockSize = file.DataBlockSize; } HeaderData hd = null; if (parameters != null && parameters.Length > 0) { foreach (KeyValuePair <string, object> o in parameters) { switch (o.Key) { case "HasMruSegments": break; case "HeaderData": hd = (HeaderData)o.Value; break; default: if (o.Key == "DataBlockDriver" && o.Value != null) { DataBlockDriver = (IDataBlockDriver)o.Value; } break; } } } if (DataBlockDriver == null) { DataBlockDriver = new DataBlockDriver(this, hd); } else { if (DataBlockDriver.HeaderData == null) { DataBlockDriver.HeaderData = hd ?? new HeaderData(DataBlockSize); } } if (MruManager == null) { int min = MruMinCapacity; int max = MruMaxCapacity; //MruManager = new ConcurrentMruManager(min, max); MruManager = new MruManager(min, max); MruManager.SetDataStores(this, DataBlockDriver); } if (_diskBuffer == null) { _diskBuffer = CreateBlock(); //new Sop.DataBlock(DataBlockSize); } }