Example #1
0
        private void PackSlotFillers(BTreeAlgorithm parent, System.IO.BinaryWriter writer,
                                     object simpleKey, ref int keySizeOnDisk, ref byte[] keyOfEmptySlots)
        {
            // write filler space same size as VersionNumber
            CollectionOnDisk.WritePersistentData(parent, 0L, writer);

            // write filler space same size as Key
            if (keySizeOnDisk > 0 || simpleKey == null)
            {
                if (keySizeOnDisk == 0)
                {
                    keySizeOnDisk  = 20;
                    keySizeOnDisk += (sizeof(long) * 2);
                }
                if (keyOfEmptySlots == null)
                {
                    keyOfEmptySlots = new byte[keySizeOnDisk];
                }
                CollectionOnDisk.WritePersistentData(parent, keyOfEmptySlots, writer, ItemType.Key);
            }
            else
            {
                CollectionOnDisk.WritePersistentData(parent, simpleKey, writer, ItemType.Key);
            }

            // write filler space same size as Value's Address on disk
            //CollectionOnDisk.WritePersistentData(parent, -1L, writer);
        }
Example #2
0
        //** todo: 1/7/09: Copy On Write(COW) each Register block to a backup file that
        //** gets overwritten over and over as only last activity detail data is logged/rolled back
        //** NOTE: older activities are deemed successful if there is a newer activity(ie - the last activity)

        //** idea:
        // 1. track new Add/Growth segments, don't track Save on said segments as,
        //** they can be stashed away without harm as only added on transaction that will be rolled
        //** back if failed/program crash
        // 2. track updated segments not in Add/Growth to allow rollback of said segments.
        // 3. last action entry will be rolled back on restart...

        protected internal override void RegisterAdd(CollectionOnDisk collection, long blockAddress, int blockSize)
        {
            //** all transaction collections reside in TransactionFile which will be rolled back and
            //** truncated during restart after program crash...
            Transaction.RegisterAdd(_addStore, _fileGrowthStore, _recycledCollectionStore, collection, blockAddress,
                                    blockSize, true);
        }
Example #3
0
        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;
        }
Example #4
0
 protected internal override void RegisterFileGrowth(CollectionOnDisk collection, long segmentAddress,
                                                     long segmentSize)
 {
     //** all transaction collections reside in TransactionFile which will be rolled back and
     //** truncated during restart after program crash...
     Transaction.RegisterFileGrowth(_fileGrowthStore, collection, segmentAddress, segmentSize, false);
 }
Example #5
0
        /// <summary>
        /// RegisterAdd will be called whenever a "new" block is allocated.
        /// Don't save block at this point as changes not saved yet.
        /// </summary>
        /// <param name="collection"></param>
        /// <param name="blockAddress"></param>
        /// <param name="blockSize"></param>
        protected internal override void RegisterAdd(CollectionOnDisk collection, long blockAddress, int blockSize)
        {
            if (IsTransactionStore(collection))
            {
                ((TransactionBase)collection.ParentTransactionLogger).RegisterAdd(collection, blockAddress, blockSize);
                return;
            }
            if (LogCollection == null)
            {
                return;
            }
            RecordKey key = CreateKey(collection, blockAddress);

            //** Check if Block is in Growth Segments
            if (RegionLogic.IsSegmentInStore(_fileGrowthStore, key, blockSize) ||
                RegionLogic.IsSegmentInStore(_recycledSegmentsStore, key, blockSize))
            {
                if (_inCommit == 0)
                {
                    TrackModification(collection.GetTopParent());
                }
                return;
            }
            RegisterAdd(_addBlocksStore, _fileGrowthStore, _recycledSegmentsStore, collection, blockAddress,
                        blockSize, false);
            if (_inCommit == 0)
            {
                TrackModification(collection.GetTopParent());
            }
        }
Example #6
0
 private void RegisterRemovedBlock(CollectionOnDisk container, long blockAddress, int blockSize)
 {
     // register removed block
     if (container.Transaction != null)
     {
         ((Transaction.TransactionBase)container.Transaction).Register(
             Sop.Transaction.ActionType.Remove, (CollectionOnDisk)container, blockAddress, blockSize);
     }
 }
Example #7
0
 private void PackSlotItem(BTreeAlgorithm parent, System.IO.BinaryWriter writer,
                           BTreeItemOnDisk slot, ref int keySizeOnDisk, bool?isKeySimpleType)
 {
     if (slot != null)
     {
         IO.OnDiskBinaryWriter _writer = (IO.OnDiskBinaryWriter)writer;
         long streamPos = _writer.LogicalPosition;
         if (slot.Value.IsDirty)
         {
             slot.VersionNumber++;
         }
         CollectionOnDisk.WritePersistentData(parent, slot.VersionNumber, writer);
         CollectionOnDisk.WritePersistentData(parent, slot.Key, writer, ItemType.Key);
         if (parent.IsDataInKeySegment)
         {
             if (parent.IsDataLongInt)
             {
                 writer.Write((long)slot.Value.Data);
             }
             else
             {
                 if (parent.PersistenceType == PersistenceType.Unknown)
                 {
                     parent.PersistenceType =
                         CollectionOnDisk.GetPersistenceType(parent, slot.Value.Data, ItemType.Value);
                     parent.IsDirty = true;
                 }
                 //** write the value and keep track of its data size and location in the disk buffer.
                 //slot.ValueBlockIndex = DiskBuffer.GetIndexOf(((OnDiskBinaryWriter)writer).DataBlock);
                 //slot.ValueIndexInBlock = ((OnDiskBinaryWriter) writer).DataBlockPosition;
                 long startPos = _writer.LogicalPosition;
                 //parent.PersistenceType
                 CollectionOnDisk.WritePersistentData(parent, slot.Value.Data, writer, ItemType.Value);
                 slot.HintSizeOnDisk = (int)(_writer.LogicalPosition - startPos);
                 //**
             }
             slot.Value.IsDirty = false;
         }
         else
         {
             if (slot.Value.diskBuffer == null)
             {
                 slot.Value.DiskBuffer = parent.CreateBlock();   //new Sop.DataBlock(parent.DataBlockSize);
             }
             writer.Write(parent.GetId(slot.Value.DiskBuffer));
         }
         if (keySizeOnDisk == 0)
         {
             int keyDataSize = (int)(_writer.LogicalPosition - streamPos);
             keySizeOnDisk            = keyDataSize;
             parent.HintKeySizeOnDisk = keyDataSize;
         }
     }
 }
Example #8
0
        protected internal override void RegisterRecycleCollection(CollectionOnDisk collection,
                                                                   long blockAddress,
                                                                   int blockSize)
        {
            RecordKey key = CreateKey(collection, blockAddress);

            if (!_recycledCollectionStore.ContainsKey(key))
            {
                RegisterFileGrowth(_recycledCollectionStore, collection, blockAddress, blockSize, true);
            }
        }
Example #9
0
        internal static void RegisterAdd(
            Collections.Generic.ISortedDictionary <RecordKey, long> addStore,
            Collections.Generic.ISortedDictionary <RecordKey, long> fileGrowthStore,
            Collections.Generic.ISortedDictionary <RecordKey, long> recycledCollectionStore,
            CollectionOnDisk collection,
            long blockAddress, int blockSize, bool checkIfInGrowthSegments)
        {
            RecordKey key = CreateKey(collection, blockAddress);

            RegisterAdd(addStore, fileGrowthStore, recycledCollectionStore, key, blockSize,
                        checkIfInGrowthSegments);
        }
Example #10
0
        override internal protected void TrackModification(CollectionOnDisk collection, bool untrack = false)
        {
            CollectionOnDisk p   = collection; // Collection.GetTopParent();
            RecordKey        key = CreateKey(p);

            if (!untrack)
            {
                ModifiedCollections[key] = p;
                return;
            }
            ModifiedCollections.Remove(key);
        }
Example #11
0
        private bool IsInUpdatedBlocks(CollectionOnDisk collection, long blockAddress, int blockSize)
        {
            BackupDataLogKey logKey = new BackupDataLogKey();

            logKey.SourceFilename    = collection.File.Filename;
            logKey.SourceDataAddress = blockAddress;
            IEnumerable <KeyValuePair <BackupDataLogKey, BackupDataLogValue> > intersectingLogs;
            long mergedBlockStartAddress, mergedBlockSize;

            return(GetIntersectingLogs(logKey, blockSize, out intersectingLogs, out mergedBlockStartAddress,
                                       out mergedBlockSize) &&
                   intersectingLogs == null);
        }
Example #12
0
 /// <summary>
 /// Register file growth
 /// </summary>
 /// <param name="collection"></param>
 /// <param name="segmentAddress"></param>
 /// <param name="segmentSize"></param>
 protected internal override void RegisterFileGrowth(CollectionOnDisk collection, long segmentAddress,
                                                     long segmentSize)
 {
     if (IsTransactionStore(collection))
     {
         ((TransactionBase)collection.ParentTransactionLogger).RegisterFileGrowth(collection, segmentAddress,
                                                                                  segmentSize);
         return;
     }
     if (LogCollection != null)
     {
         RegisterFileGrowth(_fileGrowthStore, collection, segmentAddress, segmentSize, false);
     }
 }
Example #13
0
        /// <summary>
        /// Pack this Item for serialization to disk
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="writer"></param>
        public virtual void Pack(IInternalPersistent parent, System.IO.BinaryWriter writer)
        {
            bool isReference = Value.DiskBuffer.DataAddress > -1;

            writer.Write(isReference);
            if (isReference)
            {
                writer.Write(Value.DiskBuffer.DataAddress);
            }
            else
            {
                CollectionOnDisk.WritePersistentData(parent, Value, writer);
            }
        }
Example #14
0
        /// <summary>
        /// Unpack or read the contents of this object from a Binary Reader.
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="reader"></param>
        public override void Unpack(IInternalPersistent parent, System.IO.BinaryReader reader)
        {
            DataIsUserDefined = false;
            bool?r = CollectionOnDisk.ReadPersistentData(parent, reader, ref Data);

            if (r == null)
            {
                DataIsUserDefined = true;
            }
            else if (!r.Value)
            {
                Data = null;
            }
        }
Example #15
0
 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);
 }
Example #16
0
 protected internal override bool RegisterRecycle(CollectionOnDisk collection, long blockAddress,
                                                  int blockSize)
 {
     if (!Transaction.RegisterRecycle(_addBlocksStore, _recycledBlocksStore, collection, blockAddress, blockSize))
     {
         using (var writePool = new ConcurrentIOPoolManager())
         {
             using (var readPool = new ConcurrentIOPoolManager())
             {
                 RegisterSave(collection, blockAddress, blockSize, readPool, writePool);
             }
         }
     }
     return(true);
 }
Example #17
0
        internal static bool RegisterRecycle(
            Collections.Generic.ISortedDictionary <RecordKey, long> addStore,
            Collections.Generic.ISortedDictionary <RecordKey, long> recycleStore,
            CollectionOnDisk collection,
            long blockAddress,
            int blockSize)
        {
            var key = CreateKey(collection, blockAddress);
            //if (InStore(key, blockSize, recycleStore))
            //    return false;

            BackupDataLogKey logKey = new BackupDataLogKey();

            logKey.SourceFilename    = collection.File.Filename;
            logKey.SourceDataAddress = blockAddress;
            IEnumerable <KeyValuePair <BackupDataLogKey, BackupDataLogValue> > intersectingLogs;
            long mergedBlockStartAddress, mergedBlockSize;

            if (GetIntersectingLogs(logKey, blockSize, out intersectingLogs,
                                    out mergedBlockStartAddress, out mergedBlockSize))
            {
                if (intersectingLogs == null)
                {
                    RegisterAdd(addStore, null, null, collection, blockAddress, blockSize, false);
                    return(true);
                }
                // get area(s) outside each intersecting segment and back it up...
                Region newRegion      = new Region(blockAddress, blockSize);
                bool   wasIntersected = false;
                foreach (KeyValuePair <BackupDataLogKey, BackupDataLogValue> entry in intersectingLogs)
                {
                    if (newRegion.Subtract(entry.Key.SourceDataAddress, entry.Value.DataSize))
                    {
                        wasIntersected = true;
                    }
                }
                if (wasIntersected)
                {
                    foreach (KeyValuePair <long, int> newArea in newRegion)
                    {
                        RegisterAdd(addStore, null, null, collection, newArea.Key, newArea.Value, false);
                    }
                    return(true);
                }
            }
            RegisterAdd(addStore, null, null, collection, blockAddress, blockSize, false);
            return(true);
        }
Example #18
0
 protected internal override void RegisterRemove(CollectionOnDisk collection)
 {
     if (IsTransactionStore(collection))
     {
         ((TransactionBase)collection.ParentTransactionLogger).RegisterRemove(collection);
         return;
     }
     if (LogCollection == null)
     {
         return;
     }
     if (_inCommit == 0)
     {
         TrackModification(collection.GetTopParent());
     }
 }
Example #19
0
 /// <summary>
 /// Recycle DataSet, KeySet and DeletedBlocks' Segments
 /// </summary>
 public override void Delete()
 {
     if (DataBlockDriver != null)
     {
         RemoveDeletedDataBlocks();
         CollectionOnDisk   cod = GetTopParent();
         IDataBlockRecycler db  = cod.deletedBlocks;
         cod.deletedBlocks = null;
         if (DataSet != null)
         {
             DataSet.Delete();
         }
         cod.deletedBlocks = db;
     }
     base.Delete();
 }
Example #20
0
        public void Register(ActionType action,
                             CollectionOnDisk collection,
                             long blockAddress,
                             long blockSize)
        {
            switch (action)
            {
            case ActionType.Add:
                if (blockSize > (long)DataBlockSize.Maximum)
                {
                    throw new ArgumentOutOfRangeException("blockSize");
                }
                RegisterAdd(collection, blockAddress, (int)blockSize);
                break;

            case ActionType.Remove:
                if (blockSize > int.MaxValue)
                {
                    throw new ArgumentOutOfRangeException("Register: ActionType.Remove blockSize is bigger than int.MaxValue.");
                }
                RegisterRemove(collection, blockAddress, (int)blockSize);
                break;

            case ActionType.Grow:
                RegisterFileGrowth(collection, blockAddress, blockSize);
                break;

            case ActionType.Recycle:
                if (blockSize > int.MaxValue)
                {
                    throw new ArgumentOutOfRangeException("Register: ActionType.Recycle blockSize is bigger than int.MaxValue.");
                }
                RegisterRecycle(collection, blockAddress, (int)blockSize);
                break;

            case ActionType.RecycleCollection:
                if (blockSize > int.MaxValue)
                {
                    throw new ArgumentOutOfRangeException("blockSize");
                }
                RegisterRecycleCollection(collection, blockAddress, (int)blockSize);
                break;

            default:
                throw new SopException(string.Format("Unsupported Transaction Action {0}", action));
            }
        }
Example #21
0
        internal bool ResurfaceDeletedBlockNextSegment(CollectionOnDisk parent,
                                                       DeletedBlockInfo dbi, long segmentEnd)
        {
            //** read next segment of deleted collection
            Sop.DataBlock db      = CreateBlock(parent.DataBlockSize);
            long          address = segmentEnd - (int)parent.DataBlockSize;

            db = ReadBlockFromDisk(parent, address, true, true, db);
            if (db.InternalNextBlockAddress >= 0)
            {
                dbi.StartBlockAddress = db.InternalNextBlockAddress;
                if (parent.File.DeletedCollections != null)
                {
                    parent.File.DeletedCollections.SetTop(dbi);
                }
                return(true);
            }
            return(false);
        }
Example #22
0
        /// <summary>
        /// Create/Get Data Store for IPersistent typed Key and "Simple typed" Value.
        /// NOTE: Simple type means one of the integer, numeric(decimals,...), char data types, byte array
        /// or a string
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="createIfNotExist"></param>
        /// <param name="container"></param>
        /// <param name="comparer"></param>
        /// <param name="name"></param>
        /// <param name="isDataInKeySegment"> </param>
        /// <param name="mruManaged"> </param>
        /// <returns></returns>
        public ISortedDictionary <TKey, TValue> GetPersistentKey <TKey, TValue>(object container, string name,
                                                                                System.Collections.Generic.IComparer <TKey> comparer = null,
                                                                                bool createIfNotExist   = true,
                                                                                bool isDataInKeySegment = true,
                                                                                bool mruManaged         = true)
            where TKey : IPersistent, new()
        {
            if (!CollectionOnDisk.IsSimpleType(typeof(TValue)))
            {
                throw new ArgumentException(string.Format("Type of TValue ({0}) isn't an SOP simple type.",
                                                          typeof(TValue)));
            }

            BTreeAlgorithm.CurrentOnValueUnpack =
                PersistentTypeKeySimpleValue <TKey, TValue> .Collection_OnKeyUnpack;

            var r2 = CreateDictionary <PersistentTypeKeySimpleValue <TKey, TValue>, TKey, TValue>(createIfNotExist,
                                                                                                  container, name,
                                                                                                  containerDod =>
            {
                var
                r =
                    new PersistentTypeKeySimpleValue
                    <TKey,
                     TValue
                    >(
                        container,
                        comparer,
                        name,
                        DataStoreType
                        .
                        SopOndisk,
                        null,
                        isDataInKeySegment);
                containerDod.
                SetCurrentValueInMemoryData
                    (r);
                return(r);
            }, mruManaged);

            return(r2);
        }
Example #23
0
        protected internal override void RegisterRemove(CollectionOnDisk collection, long blockAddress, int blockSize)
        {
            if (IsTransactionStore(collection))
            {
                ((TransactionBase)collection.ParentTransactionLogger).RegisterRemove(collection, blockAddress, blockSize);
                return;
            }
            if (LogCollection == null)
            {
                return;
            }


            if (_inCommit == 0)
            {
                TrackModification(collection.GetTopParent());
            }

            // object o = 90;   // todo: remove return when ready...
            return;


            // Check if Block is in Growth, RecycledCollection, Add, Recycled blocks segments...
            RecordKey key = CreateKey(collection, blockAddress);

            if (RegionLogic.IsSegmentInStore(_fileGrowthStore, key, blockSize) ||
                RegionLogic.IsSegmentInStore(_recycledSegmentsStore, key, blockSize) ||
                RegionLogic.IsSegmentInStore(_addBlocksStore, key, blockSize))
            {
                return;
            }
            // check if block is in updated blocks...
            if (IsInUpdatedBlocks(collection, blockAddress, blockSize))
            {
                return;
            }
            AddMerge(_recycledBlocksStore, key, blockSize);
            if (_inCommit == 0)
            {
                TrackModification(collection.GetTopParent());
            }
        }
Example #24
0
        private void RemoveInMemory(CollectionOnDisk coll, long address)
        {
            bool             reload = false;
            CollectionOnDisk p      = coll;

            while (p != null)
            {
                if (p.RemoveInMemory(address, this) && !reload)
                {
                    reload = true;
                }
                if (p.Parent is CollectionOnDisk)
                {
                    p = (CollectionOnDisk)p.Parent;
                }
                else
                {
                    return;
                }
            }
        }
Example #25
0
        private void BackupData(CollectionOnDisk collection, long blockAddress, int segmentSize)
        {
            if (_loggerTransDetailsFileStream == null)
            {
                int bufferSize;
                //** open with 1 MB custom buffering
                string s = _loggerTransDetailsLogFilename;
                if (Server != null)
                {
                    s = Server.NormalizePath(s);
                }
                _loggerTransDetailsFileStream = File.UnbufferedOpen(s, out bufferSize).RealStream;
                _loggerTransDetailsBuffer     = new byte[bufferSize];
            }
            long sourceOffset = collection.FileStream.Position;

            collection.FileStream.Seek(blockAddress, System.IO.SeekOrigin.Begin);
            //** copy asynchronously from source to target log file
            IAsyncResult iar = collection.FileStream.BeginRead(_loggerTransDetailsBuffer, 0, segmentSize, null, null);

            if (!iar.IsCompleted)
            {
                iar.AsyncWaitHandle.WaitOne();
            }
            collection.FileStream.EndRead(iar);
            _loggerTransDetailsFileStream.Seek(0, System.IO.SeekOrigin.Begin);
            iar = _loggerTransDetailsFileStream.BeginWrite(_loggerTransDetailsBuffer, 0, segmentSize, null, null);
            if (!iar.IsCompleted)
            {
                iar.AsyncWaitHandle.WaitOne();
            }
            _loggerTransDetailsFileStream.EndWrite(iar);
            _loggerTransDetailsFileStream.Flush();
            if (_loggerTransDetailsFileStream.Length > segmentSize)
            {
                _loggerTransDetailsFileStream.SetLength(segmentSize);
            }
            collection.FileStream.Seek(sourceOffset, System.IO.SeekOrigin.Begin);
        }
Example #26
0
        /// <summary>
        /// Unpack this item for DeSerialization from Stream
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="reader"></param>
        public virtual void Unpack(IInternalPersistent parent, System.IO.BinaryReader reader)
        {
            bool?r = CollectionOnDisk.ReadPersistentData(parent, reader, ref Key);

            if (r == null)
            {
                if (((BTreeAlgorithm)parent).onKeyUnpack != null)
                {
                    Key = ((BTreeAlgorithm)parent).onKeyUnpack(reader);
                }
                else
                {
                    throw new SopException("Can't Deserialize Custom persisted 'Key'.");
                }
            }
            if (Value == null)
            {
                var f = (File.File)InternalPersistent.GetParent(parent, typeof(File.File));
                Value = new ItemOnDisk(f.DataBlockSize);
            }
            bool valueIsReference = reader.ReadBoolean();

            if (valueIsReference)
            {
                Value.DiskBuffer.DataAddress = reader.ReadInt64();
            }
            else
            {
                object o = Value;
                CollectionOnDisk.ReadPersistentData(parent, reader, ref o);
                Value = (ItemOnDisk)o;
                if (Value.DataIsUserDefined && ((BTreeAlgorithm)parent).onValueUnpack != null)
                {
                    Value.Data = ((BTreeAlgorithm)parent).onValueUnpack(reader);
                }
            }
            IsDirty = false;
        }
Example #27
0
        /// <summary>
        /// Commit a transaction
        /// </summary>
        /// <param name="phase">
        /// FirstPhase will make changes permanent but keep transaction log so rollback
        /// is still possible.
        ///
        /// SecondPhase will:
        /// 1. call FirstPhase commit if this transaction is in UnCommitted phase
        /// 2. clear the transaction log to complete Commit
        /// NOTE: Rollback is no longer allowed after completion of SecondPhase
        /// </param>
        ///<returns>true if successful otherwise false</returns>
        public override bool InternalCommit(CommitPhase phase)
        {
            if (CurrentCommitPhase == CommitPhase.Committed)
            {
                throw new InvalidOperationException(string.Format("Transaction '{0}' is already committed.", Id));
            }
            _inCommit++;
            try
            {
                switch (phase)
                {
                case CommitPhase.FirstPhase:
                    if (CurrentCommitPhase == CommitPhase.UnCommitted)
                    {
                        RollbackConflicts();
                        //** save all cached data of each collection
                        var parents =
                            new Dictionary <CollectionOnDisk, object>(ModifiedCollections.Count);
                        var closeColls = new List <RecordKey>();
                        foreach (KeyValuePair <RecordKey, CollectionOnDisk> kvp in ModifiedCollections)
                        {
                            CollectionOnDisk collection = kvp.Value;
                            CollectionOnDisk ct         = collection.GetTopParent();
                            if (ct.IsOpen)
                            {
                                parents[ct] = null;
                            }
                            else
                            {
                                closeColls.Add(kvp.Key);
                            }
                        }
                        foreach (CollectionOnDisk collection in parents.Keys)
                        {
                            if (!collection.IsOpen)
                            {
                                continue;
                            }
                            collection.Flush();
                            collection.OnCommit();
                        }
                        foreach (RecordKey k in closeColls)
                        {
                            ModifiedCollections.Remove(k);
                        }
                        //File.DeletedCollections.Flush();
                        CurrentCommitPhase = CommitPhase.FirstPhase;
                        //** don't clear transaction log so rollback is still possible
                        return(true);
                    }
                    break;

                case CommitPhase.SecondPhase:
                    if (CurrentCommitPhase == CommitPhase.UnCommitted)
                    {
                        if (!Commit(CommitPhase.FirstPhase))
                        {
                            break;
                        }
                    }
                    if (CurrentCommitPhase == CommitPhase.FirstPhase)
                    {
                        //** mark second phase completed as when it starts, no turning back...
                        CurrentCommitPhase = CommitPhase.SecondPhase;

                        //** preserve the recycled segment so on rollback it can be restored...
                        foreach (CollectionOnDisk collection in ModifiedCollections.Values)
                        {
                            if (!collection.IsOpen)
                            {
                                continue;
                            }
                            collection.HeaderData.RecycledSegmentBeforeTransaction =
                                collection.HeaderData.RecycledSegment;
                            if (collection.HeaderData.RecycledSegmentBeforeTransaction != null)
                            {
                                collection.HeaderData.RecycledSegmentBeforeTransaction =
                                    (DeletedBlockInfo)
                                    collection.HeaderData.RecycledSegmentBeforeTransaction.Clone();
                            }
                        }

                        //** delete new (AddStore), updated (LogCollection) and
                        //** file growth segments (FileGrowthStore) "log entries"
                        ClearStores(true);

                        //** todo: Record on Trans Log the FileSet Remove action + info needed for
                        //** commit resume "on crash and restart" 11/9/08

                        File.Delete(Server.Path + DataBackupFilename);

                        //** todo: remove from trans Log the FileSet Remove action... 11/09/08

                        return(true);
                    }
                    break;
                }
                //** auto roll back this transaction if commit failed above
                if (CurrentCommitPhase != CommitPhase.Rolledback &&
                    CurrentCommitPhase != CommitPhase.SecondPhase)
                {
                    Rollback();
                }
                return(false);
            }
            finally
            {
                _inCommit--;
                if (Parent == null)
                {
                    CollectionOnDisk.transaction = null;
                }
                else
                {
                    Parent.Children.Remove(this);
                }
            }
        }
Example #28
0
        /// <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)
                      );
        }
Example #29
0
 protected internal virtual void TrackModification(CollectionOnDisk collection, bool untrack = false)
 {
 }
Example #30
0
 protected internal abstract void RegisterRecycleCollection(CollectionOnDisk collection,
                                                            long blockAddress, int blockSize);