internal static int SizeOfMetaData(IInternalPersistent parent) { if (parent == null) { throw new ArgumentNullException("parent"); } if (!(parent is CollectionOnDisk)) { throw new ArgumentException("Parent is not CollectionOnDisk type."); } if (Encoding != ((CollectionOnDisk)parent).File.Server.Encoding) { Encoding = ((CollectionOnDisk)parent).File.Server.Encoding; _sizeOf = 0; } if (_sizeOf == 0) { var o = new LinkedItemOnDisk { DiskBuffer = ((CollectionOnDisk)parent).DataBlockDriver. CreateBlock(((CollectionOnDisk)parent).File.DataBlockSize), Data = new byte[0] }; var w = new OnDiskBinaryWriter(Encoding) { DataBlock = o.DiskBuffer }; WritePersistentData(parent, o, w); _sizeOf = (int)w.BaseStream.Position; w.Close(); } return(_sizeOf); }
public override void Clear() { if (Count <= 0) { return; } FirstItem = new LinkedItemOnDisk(File.DataBlockSize); this.CurrentItem = FirstItem; LastItem = new LinkedItemOnDisk(File.DataBlockSize); base.Clear(); }
/// <summary> /// Add 'Value' to the Collection /// </summary> public long Add(object value) { var o = new LinkedItemOnDisk(this.DataBlockSize) { Data = value }; WriteToDisk(o, false); UpdateCount(UpdateCountType.Increment); //*** update Current, Last & First if (LastItem.DiskBuffer.DataAddress != -1) { o.PreviousItemAddress = LastItem.DiskBuffer.DataAddress; WriteToDisk(o, false); LinkedItemOnDisk biod = CurrentItem; biod.NextItemAddress = o.DiskBuffer.DataAddress; Sop.DataBlock db = DataBlockDriver.ReadBlockFromDisk(this, LastItem.DiskBuffer.DataAddress, true); if (CurrentItem.DiskBuffer.DataAddress != LastItem.DiskBuffer.DataAddress) { biod = (LinkedItemOnDisk)ReadFromBlock(db); biod.NextItemAddress = o.DiskBuffer.DataAddress; } else { PurifyMeta(biod, db); if (db.SizeOccupied > 0) { biod.DiskBuffer = db; } } WriteToDisk(biod, false); } else { FirstItem.DiskBuffer.DataAddress = o.DiskBuffer.DataAddress; } currentEntry = null; CurrentItem = o; CurrentEntryDataAddress = o.DiskBuffer.DataAddress; currentDataBlock = o.DiskBuffer; LastItem.DiskBuffer.DataAddress = o.DiskBuffer.DataAddress; MruManager.Add(CurrentEntryDataAddress, o); //** update the header RegisterChange(true); //IsDirty = true; return(o.DiskBuffer.DataAddress); }
/// <summary> /// Shared Block on Disk purifies data and only saves one /// copy of Meta data in it. /// </summary> /// <param name="biod"></param> /// <param name="db"></param> protected override void PurifyMeta(LinkedItemOnDisk biod, Sop.DataBlock db) { if (db.SizeOccupied > 0) { //** purify data by separating meta data from it so meta data won't be serialized more than once int metaDataSize = LinkedListOnDisk.SizeOfMetaData(this); int newSize = db.SizeOccupied - metaDataSize; byte[] newData = new byte[newSize]; Array.Copy(db.Data, metaDataSize, newData, 0, newSize); //** assign data to block for serialization biod.Data = newData; } }
public override void Unpack(IInternalPersistent parent, BinaryReader reader) { if (CurrentItem == null) { FirstItem = new LinkedItemOnDisk(File.DataBlockSize); LastItem = new LinkedItemOnDisk(File.DataBlockSize); } CurrentItem = FirstItem; long firstItemDataAddress = reader.ReadInt64(); long lastItemDataAddress = reader.ReadInt64(); FirstItem.DiskBuffer.DataAddress = firstItemDataAddress; LastItem.DiskBuffer.DataAddress = lastItemDataAddress; base.Unpack(parent, reader); }
/// <summary> /// MoveFirst makes the first entry in the Collection the current one /// </summary> public override bool MoveFirst() { if (Count > 0 && CurrentItem != null) { if (FirstItem.DiskBuffer.DataAddress != CurrentEntryDataAddress || FirstItem.DiskBuffer.DataAddress != CurrentItem.DiskBuffer.DataAddress) { CurrentEntryDataAddress = -1; this.DataBlockDriver.MoveTo(this, FirstItem.DiskBuffer.DataAddress); Sop.DataBlock db = DataBlockDriver.ReadBlockFromDisk(this, FirstItem.DiskBuffer.DataAddress, false); this.currentDataBlock = db; CurrentItem = (LinkedItemOnDisk)ReadFromBlock(db); } return(true); } return(false); }
protected internal override void Initialize(File.IFile file, params KeyValuePair <string, object>[] parameters) { base.Initialize(file, parameters); if (FirstItem == null) { FirstItem = new LinkedItemOnDisk(file.DataBlockSize); } if (CurrentItem == null) { CurrentItem = FirstItem; } if (LastItem == null) { LastItem = new LinkedItemOnDisk(file.DataBlockSize); } //** don't call open here, let caller code do it to ensure proper "state" when Open is called!! }
public override void Close() { if (!IsOpen) { return; } base.Close(); if (OnDiskBinaryWriter != null) { OnDiskBinaryWriter.Close(); OnDiskBinaryWriter = null; } if (OnDiskBinaryReader != null) { OnDiskBinaryReader.Close(); OnDiskBinaryReader = null; } FirstItem = new LinkedItemOnDisk(File.DataBlockSize); this.CurrentItem = FirstItem; LastItem = new LinkedItemOnDisk(File.DataBlockSize); }
//internal override bool RemoveInMemory(long DataAddress, Transaction.ITransactionLogger Transaction) //{ // if (LastItem != null) // LastItem.Clear(); // if (FirstItem != null) // FirstItem.Clear(); // CurrentItem = null; // base.RemoveInMemory(DataAddress, Transaction); // return true; //} private void RemoveAt(long dataAddress, bool willMove) { if (willMove && !MoveTo(dataAddress)) { return; } if (IsDeletedBlocksList && Count == 1) { return; } Sop.DataBlock currBlock = this.GetCurrentDataBlock(true); if (FirstItem.DiskBuffer.DataAddress == dataAddress) { MoveFirst(); if (MoveNext()) { FirstItem.DiskBuffer.DataAddress = CurrentItem.DiskBuffer.DataAddress; CurrentItem.PreviousItemAddress = -1; Sop.DataBlock db = WriteToBlock(CurrentItem, CurrentItem.DiskBuffer); DataBlockDriver.SetDiskBlock(this, db, false); } else { long address = FirstItem.DiskBuffer.DataAddress; FirstItem.DiskBuffer.DataAddress = LastItem.DiskBuffer.DataAddress = -1; CurrentItem = FirstItem; Sop.DataBlock db = WriteToBlock(CurrentItem, CurrentItem.DiskBuffer); db.DataAddress = address; DataBlockDriver.SetDiskBlock(this, db, false); db.DataAddress = -1; } } else if (LastItem.DiskBuffer.DataAddress == dataAddress) { if (MovePrevious() || FirstItem.DiskBuffer.DataAddress == CurrentItem.DiskBuffer.DataAddress) { LastItem.DiskBuffer.DataAddress = CurrentItem.DiskBuffer.DataAddress; CurrentItem.NextItemAddress = -1; Sop.DataBlock db = WriteToBlock(CurrentItem, CurrentItem.DiskBuffer); DataBlockDriver.SetDiskBlock(this, db, false); } else { throw new InvalidOperationException("Can't go previous but First is not the only item."); } } else { LinkedItemOnDisk curr = CurrentItem; LinkedItemOnDisk prev = null, next = null; if (MoveTo(curr.PreviousItemAddress)) { prev = CurrentItem; } if (MoveTo(curr.NextItemAddress)) { next = CurrentItem; } if (prev != null && next != null) { prev.NextItemAddress = curr.NextItemAddress; next.PreviousItemAddress = curr.PreviousItemAddress; Sop.DataBlock db = WriteToBlock(prev, prev.DiskBuffer); DataBlockDriver.SetDiskBlock(this, db, false); db = WriteToBlock(next, next.DiskBuffer); DataBlockDriver.SetDiskBlock(this, db, false); } } if (MruManager.Count > 0) { MruManager.Remove(dataAddress, true); } DataBlockDriver.Remove(this, currBlock); }
/// <summary> /// Allows child class to purify Meta data from data /// </summary> /// <param name="biod"></param> /// <param name="db"></param> protected virtual void PurifyMeta(LinkedItemOnDisk biod, Sop.DataBlock db) { }