Esempio n. 1
0
        /// <summary>
        /// RegisterSave is the only one we do COW to be able to roll back from text log file
        /// the last transaction action done.
        /// </summary>
        /// <param name="collection"></param>
        /// <param name="blockAddress"></param>
        /// <param name="segmentSize"></param>
        /// <param name="readPool"> </param>
        /// <param name="writePool"> </param>
        protected internal override bool RegisterSave(CollectionOnDisk collection, long blockAddress, int segmentSize,
                                                      ConcurrentIOPoolManager readPool, ConcurrentIOPoolManager writePool)
        {
            if (!string.IsNullOrEmpty(_lastRegisterSaveFilename))
            {
                LoggerTransDetails.Log(string.Format("Successful RegisterSave {0}, {1}, {2}",
                                                     _lastRegisterSaveFilename, _lastRegisterSaveBlockAddress,
                                                     _lastRegisterSaveSegmentSize));
                _lastRegisterSaveFilename     = null;
                _lastRegisterSaveBlockAddress = 0;
                _lastRegisterSaveSegmentSize  = 0;
            }

            /* Step 1. Remove Intersections with added/recycled Blocks from region as no need to backup
             *       new Blocks
             * Step 2. Copy or backup (any) remaining blocks (the Updated blocks)
             *       onto the Transaction Log file for restore on Rollback
             */
            Transaction.RecordKey key = Transaction.CreateKey(collection, blockAddress);

            Region region = RegionLogic.RemoveIntersections(_fileGrowthStore, key,
                                                            blockAddress, segmentSize);

            if (region == null || region.Count == 0)
            {
                return(false);
            }

            bool logOnce = false;

            foreach (KeyValuePair <long, int> area2 in region)
            {
                key.Address = area2.Key;

                Region region2 = RegionLogic.RemoveIntersections(_recycledCollectionStore, key,
                                                                 area2.Key, area2.Value);

                if (region2 != null && region.Count > 0)
                {
                    foreach (KeyValuePair <long, int> area3 in region2)
                    {
                        key.Address = area3.Key;

                        Region region3 = RegionLogic.RemoveIntersections(_addStore, key,
                                                                         area3.Key, area3.Value);

                        //** Step 2: Backup the "modified" portion(s) of data
                        if (region3 != null && region3.Count > 0)
                        {
                            //** foreach disk area in region, copy it to transaction log file
                            foreach (KeyValuePair <long, int> area4 in region3)
                            {
                                BackupData(collection, area4.Key, area4.Value);
                            }
                            if (!logOnce)
                            {
                                logOnce = true;
                                _lastRegisterSaveFilename     = collection.File.Filename;
                                _lastRegisterSaveBlockAddress = blockAddress;
                                _lastRegisterSaveSegmentSize  = segmentSize;
                                LoggerTransDetails.Log(
                                    string.Format("RegisterSave {0}, {1}, {2}", collection.File.Filename, blockAddress,
                                                  segmentSize));
                            }
                        }
                    }
                }
            }
            return(logOnce);
        }
Esempio n. 2
0
        /// <summary>
        /// RegisterSave will be called when a block cache faulted from memory
        /// onto Disk. Resolution of Added blocks will be done here and only
        /// those "modified" blocks will be registered & backed up.
        /// </summary>
        /// <param name="collection">Collection that is saving the block</param>
        /// <param name="blockAddress"></param>
        /// <param name="segmentSize"></param>
        /// <param name="readPool"> </param>
        /// <param name="writePool"> </param>
        protected internal override bool RegisterSave(CollectionOnDisk collection, long blockAddress,
                                                      int segmentSize, ConcurrentIOPoolManager readPool, ConcurrentIOPoolManager writePool)
        {
            if (IsTransactionStore(collection))
            {
                return(((TransactionBase)collection.ParentTransactionLogger).RegisterSave(collection, blockAddress,
                                                                                          segmentSize, readPool,
                                                                                          writePool));
            }
            if (LogCollection == null)
            {
                return(false);
            }

            LogTracer.Verbose("Transactin.RegisterSave: Start for Thread {0}.", Thread.CurrentThread.ManagedThreadId);

            //Step 1. Remove Intersections with Added, Growth segments & Recycled Blocks from region as no need to backup
            //         new Blocks
            //Step 2. Copy or backup remaining (Updated) blocks onto the Transaction Log file for restore on Rollback
            RecordKey key = CreateKey(collection, blockAddress);

            // if in file growth segments, don't register for save...
            Region region = RegionLogic.RemoveIntersections(_fileGrowthStore, key, blockAddress, segmentSize);

            if (region == null || region.Count == 0)
            {
                if (_inCommit == 0)
                {
                    TrackModification(collection.GetTopParent());
                }
                return(false);
            }

            #region subtract any region intersecting with recycled and add Stores
            int itemCount = region.Count / 2;
            if (itemCount < 5)
            {
                itemCount = 5;
            }
            var regionsForBackup = new List <KeyValuePair <RecordKey, Region> >(itemCount);

            foreach (KeyValuePair <long, int> area in region)
            {
                // subtract regions intersecting with recycled segments
                key.Address = area.Key;
                Region region2 = RegionLogic.RemoveIntersections(_recycledSegmentsStore,
                                                                 key, area.Key, area.Value);

                LogTracer.Verbose("Transactin.RegisterSave: Thread {0}, _recycledSegmentsStore count {1}.", Thread.CurrentThread.ManagedThreadId, _recycledSegmentsStore.Count);

                if (region2 == null || region2.Count <= 0 ||
                    ((LogCollection is SortedDictionaryOnDisk) &&
                     key.Filename == ((SortedDictionaryOnDisk)LogCollection).File.Filename))
                {
                    continue;
                }
                // subtract regions intersecting with (new) add segments
                foreach (KeyValuePair <long, int> area2 in region2)
                {
                    key.Address = area2.Key;
                    var region3 = RegionLogic.RemoveIntersections(_addBlocksStore, key, area2.Key, area2.Value);

                    LogTracer.Verbose("Transactin.RegisterSave: Thread {0}, _addBlocksStore count {1}.", Thread.CurrentThread.ManagedThreadId, _addBlocksStore.Count);

                    if (region3 == null || region3.Count <= 0)
                    {
                        continue;
                    }
                    foreach (KeyValuePair <long, int> area3 in region3)
                    {
                        key.Address = area3.Key;
                        var region4 = RegionLogic.RemoveIntersections(_recycledBlocksStore, key, area3.Key, area3.Value);

                        LogTracer.Verbose("Transactin.RegisterSave: Thread {0}, _recycledBlocksStore count {1}.", Thread.CurrentThread.ManagedThreadId, _recycledBlocksStore.Count);


                        if (region4 == null || region4.Count <= 0)
                        {
                            continue;
                        }
                        // any remaining portions are marked for backup
                        if (_inCommit == 0)
                        {
                            TrackModification(collection.GetTopParent());
                        }
                        regionsForBackup.Add(new KeyValuePair <RecordKey, Region>(key, region4));
                    }
                }
            }

            #endregion
            if (readPool != null)
            {
                BackupData(regionsForBackup, readPool, writePool);
            }
            else
            {
                BackupData(regionsForBackup);
            }
            return(true);
        }
Esempio n. 3
0
        /// <summary>
        /// RegisterSave will be called when a block cache faulted from memory
        /// onto Disk. Resolution of Added blocks will be done here and only
        /// those "modified" blocks will be saved. Newly added block(s) will
        /// not be saved.
        /// </summary>
        /// <param name="collection">Collection that is saving the block</param>
        /// <param name="blockAddress"></param>
        /// <param name="segmentSize"></param>
        /// <param name="readPool"> </param>
        /// <param name="writePool"> </param>
        protected internal override bool RegisterSave(CollectionOnDisk collection, long blockAddress,
                                                      int segmentSize, ConcurrentIOPoolManager readPool, ConcurrentIOPoolManager writePool)
        {
            if (IsTransactionStore(collection))
            {
                return(((TransactionBase)collection.ParentTransactionLogger).RegisterSave(collection, blockAddress,
                                                                                          segmentSize, readPool,
                                                                                          writePool));
            }
            if (LogCollection == null)
            {
                return(false);
            }

            /* Step 1. Remove Intersections with Added, Growth segments & Recycled Blocks from region as no need to backup
             *                           new Blocks
             *             Step 2. Copy or backup (any) remaining blocks (the Updated blocks)
             *                           onto the Transaction Log file for restore on Rollback
             */
            RecordKey key = CreateKey(collection, blockAddress);

            //// if in recycled or add store, don't register for save...
            //if (RegionLogic.IsSegmentInStore(_recycledCollectionStore, key, segmentSize) || InAddStore(key, segmentSize))
            //    return false;
            //** if in file growth segments, don't register for save...
            Region region = RegionLogic.RemoveIntersections(_fileGrowthStore, key, blockAddress, segmentSize);

            if (region == null || region.Count == 0)
            {
                if (_inCommit == 0)
                {
                    TrackModification(collection.GetTopParent());
                }
                return(false);
            }
            //**

            int itemCount = region.Count / 2;

            if (itemCount < 5)
            {
                itemCount = 5;
            }
            var regionsForBackup = new List <KeyValuePair <RecordKey, Region> >(itemCount);

            foreach (KeyValuePair <long, int> area in region)
            {
                key.Address = area.Key;
                Region region2 = RegionLogic.RemoveIntersections(_recycledCollectionStore,
                                                                 key, area.Key, area.Value);
                if (region2 == null || region2.Count <= 0 ||
                    ((LogCollection is SortedDictionaryOnDisk) &&
                     key.Filename == ((SortedDictionaryOnDisk)LogCollection).File.Filename))
                {
                    continue;
                }
                foreach (KeyValuePair <long, int> area2 in region2)
                {
                    key.Address = area2.Key;
                    Region region3 = RegionLogic.RemoveIntersections(_addStore,
                                                                     key, area2.Key, area2.Value);
                    //** Step 2: Backup the "modified" portion(s) of data
                    if (region3 == null || region3.Count <= 0)
                    {
                        continue;
                    }
                    if (_inCommit == 0)
                    {
                        TrackModification(collection.GetTopParent());
                    }
                    regionsForBackup.Add(new KeyValuePair <RecordKey, Region>(key, region3));
                }
            }
            if (readPool != null)
            {
                BackupData(regionsForBackup, readPool, writePool);
            }
            else
            {
                BackupData(regionsForBackup);
            }
            return(true);
        }