Пример #1
0
        /// <summary>
        /// Check whether a block is a newly added block or is in new segment or recycle store.
        /// </summary>
        /// <param name="addStore"></param>
        /// <param name="fileGrowthStore"></param>
        /// <param name="recycledCollectionStore"></param>
        /// <param name="key"></param>
        /// <param name="blockSize"></param>
        /// <param name="checkIfInGrowthSegments"></param>
        /// <returns>true if block is either new, in new segment or in recycle store, false otherwise</returns>
        internal static void RegisterAdd(
            Collections.Generic.ISortedDictionary <RecordKey, long> addStore,
            Collections.Generic.ISortedDictionary <RecordKey, long> fileGrowthStore,
            Collections.Generic.ISortedDictionary <RecordKey, long> recycledCollectionStore,
            RecordKey key, int blockSize, bool checkIfInGrowthSegments)
        {
            //** Check if Block is in Growth Segments
            if (checkIfInGrowthSegments &&
                (RegionLogic.IsSegmentInStore(fileGrowthStore, key, blockSize) ||
                 RegionLogic.IsSegmentInStore(recycledCollectionStore, key, blockSize)))
            {
                return;
            }

            //** Add Block to AddStore for use on Rollback...
            if (!addStore.ContainsKey(key))
            {
                short passCount = 0;
                //** Detect and merge contiguous blocks
                if (!addStore.MovePrevious())
                {
                    addStore.MoveFirst();
                }
                while (!addStore.EndOfTree())
                {
                    var       de = addStore.CurrentEntry;
                    RecordKey k2 = de.Value.Key;
                    long      i  = de.Value.Value;
                    if (k2.ServerSystemFilename == key.ServerSystemFilename &&
                        k2.Filename == key.Filename &&
                        k2.CollectionName == key.CollectionName)
                    {
                        if (key.Address + blockSize == k2.Address)
                        {
                            long newSize = i + blockSize;
                            addStore.Remove(de.Value.Key);
                            k2.Address = key.Address;
                            addStore.Add(k2, newSize);
                            return;
                        }
                        if (k2.Address + i == key.Address)
                        {
                            addStore.CurrentValue = i + blockSize;
                            return;
                        }
                        if (key.Address >= k2.Address && key.Address + blockSize <= k2.Address + i)
                        {
                            //** if block is inclusive, don't do anything...
                            return;
                        }
                    }
                    else if (++passCount >= 2)
                    {
                        break;
                    }
                    addStore.MoveNext();
                }
                addStore.Add(key, blockSize);
            }
        }
Пример #2
0
 internal static void AddMerge(
     Collections.Generic.ISortedDictionary <RecordKey, long> addStore, RecordKey key, int blockSize)
 {
     addStore.Locker.Invoke(() =>
     {
         // Add Block to AddStore for use on Rollback...
         if (!addStore.ContainsKey(key))
         {
             short passCount = 0;
             // Detect and merge contiguous blocks
             if (!addStore.MovePrevious())
             {
                 addStore.MoveFirst();
             }
             while (!addStore.EndOfTree())
             {
                 var de       = addStore.CurrentEntry;
                 RecordKey k2 = de.Value.Key;
                 long i       = de.Value.Value;
                 if (k2.ServerSystemFilename == key.ServerSystemFilename &&
                     k2.Filename == key.Filename &&
                     k2.CollectionName == key.CollectionName)
                 {
                     if (key.Address + blockSize == k2.Address)
                     {
                         long newSize = i + blockSize;
                         addStore.Remove(de.Value.Key);
                         k2.Address = key.Address;
                         addStore.Add(k2, newSize);
                         return;
                     }
                     if (k2.Address + i == key.Address)
                     {
                         addStore[de.Value.Key] = i + blockSize;
                         //addStore.CurrentValue = i + blockSize;
                         return;
                     }
                     if (key.Address >= k2.Address && key.Address + blockSize <= k2.Address + i)
                     {
                         // if block is inclusive, don't do anything...
                         return;
                     }
                 }
                 else if (++passCount >= 2)
                 {
                     break;
                 }
                 addStore.MoveNext();
             }
             addStore.Add(key, blockSize);
         }
     });
 }
Пример #3
0
 private static bool InStore(RecordKey key, int blockSize,
                             Collections.Generic.ISortedDictionary <RecordKey, long> addStore)
 {
     if (addStore == null)
     {
         throw new ArgumentNullException("addStore");
     }
     return(addStore.Locker.Invoke(() =>
     {
         if (addStore.ContainsKey(key))
         {
             return true;
         }
         short passCount = 0;
         //** Detect and merge contiguous blocks
         if (!addStore.MovePrevious())
         {
             addStore.MoveFirst();
         }
         while (!addStore.EndOfTree())
         {
             var de = addStore.CurrentEntry;
             RecordKey k2 = de.Value.Key;
             long i = de.Value.Value;
             if (k2.ServerSystemFilename == key.ServerSystemFilename &&
                 k2.Filename == key.Filename &&
                 k2.CollectionName == key.CollectionName)
             {
                 if (key.Address + blockSize == k2.Address)
                 {
                     return true;
                 }
                 if (k2.Address + i == key.Address)
                 {
                     return true;
                 }
                 if (key.Address >= k2.Address && key.Address + blockSize <= k2.Address + i)
                 {
                     //** if block is inclusive, don't do anything...
                     return true;
                 }
             }
             else if (++passCount >= 2)
             {
                 break;
             }
             addStore.MoveNext();
         }
         return false;
     }));
 }
Пример #4
0
 /// <summary>
 /// Checks whether a certain area on disk (segment)
 /// is inclusive on any of segment entries of the store.
 /// </summary>
 /// <param name="fileGrowthStore"></param>
 /// <param name="key"></param>
 /// <param name="blockSize"></param>
 /// <returns></returns>
 public bool IsSegmentInStore(
     Collections.Generic.ISortedDictionary <Transaction.Transaction.RecordKey, long> fileGrowthStore, Transaction.Transaction.RecordKey key, int blockSize)
 {
     fileGrowthStore.Locker.Lock();
     try
     {
         if (fileGrowthStore.ContainsKey(key))
         {
             return(true);
         }
         KeyValuePair <Transaction.Transaction.RecordKey, long>?de;
         Transaction.Transaction.RecordKey k2;
         short passCount = 0;
         if (!fileGrowthStore.MovePrevious())
         {
             fileGrowthStore.MoveFirst();
         }
         while (!fileGrowthStore.EndOfTree())
         {
             de = fileGrowthStore.CurrentEntry;
             if (de == null)
             {
                 break;
             }
             k2 = de.Value.Key;
             if (k2.ServerSystemFilename == key.ServerSystemFilename &&
                 k2.Filename == key.Filename)
             {
                 long i = (long)de.Value.Value;
                 if (key.Address >= k2.Address && key.Address + blockSize <= k2.Address + i)
                 {
                     return(true);
                 }
             }
             else if (++passCount >= 2)
             {
                 break;
             }
             fileGrowthStore.MoveNext();
         }
         return(false);
     }
     finally
     {
         fileGrowthStore.Locker.Unlock();
     }
 }
Пример #5
0
 private bool InAddStore(RecordKey key, int blockSize)
 {
     Collections.Generic.ISortedDictionary <RecordKey, long> addStore = _addStore;
     if (!addStore.ContainsKey(key))
     {
         short passCount = 0;
         //** Detect and merge contiguous blocks
         if (!_addStore.MovePrevious())
         {
             addStore.MoveFirst();
         }
         while (!addStore.EndOfTree())
         {
             var       de = addStore.CurrentEntry;
             RecordKey k2 = de.Value.Key;
             long      i  = de.Value.Value;
             if (k2.ServerSystemFilename == key.ServerSystemFilename &&
                 k2.Filename == key.Filename &&
                 k2.CollectionName == key.CollectionName)
             {
                 if (key.Address + blockSize == k2.Address)
                 {
                     return(true);
                 }
                 if (k2.Address + i == key.Address)
                 {
                     return(true);
                 }
                 if (key.Address >= k2.Address && key.Address + blockSize <= k2.Address + i)
                 {
                     //** if block is inclusive, don't do anything...
                     return(true);
                 }
             }
             else if (++passCount >= 2)
             {
                 break;
             }
             addStore.MoveNext();
         }
     }
     return(false);
 }
Пример #6
0
        internal static bool RegisterFileGrowth(Collections.Generic.ISortedDictionary <RecordKey, long> fileGrowthStore,
                                                CollectionOnDisk collection, long segmentAddress, long segmentSize,
                                                bool recycleCollection)
        {
            fileGrowthStore.Locker.Lock();
            try
            {
                RecordKey key = CreateKey(collection, segmentAddress);
                if (!fileGrowthStore.ContainsKey(key))
                {
                    if (!recycleCollection)
                    {
                        if (collection.Transaction is Transaction)
                        {
                            ((Transaction)collection.Transaction).AppendLogger.LogLine(
                                "{0}{1} {2} {3}", GrowToken, collection.File.Filename, segmentAddress, segmentSize);
                        }
                    }

                    if (!fileGrowthStore.MovePrevious())
                    {
                        fileGrowthStore.MoveFirst();
                    }
                    short     moveNextCount = 0;
                    RecordKey k2;
                    KeyValuePair <RecordKey, long>?de;
                    while (!fileGrowthStore.EndOfTree())
                    {
                        de = fileGrowthStore.CurrentEntry;
                        k2 = de.Value.Key;
                        long i = de.Value.Value;
                        if (k2.ServerSystemFilename == key.ServerSystemFilename &&
                            k2.Filename == key.Filename)
                        {
                            if (segmentAddress + segmentSize == k2.Address)
                            {
                                long newSize = i + segmentSize;
                                fileGrowthStore.Remove(de.Value.Key);
                                k2.Address = segmentAddress;
                                fileGrowthStore.Add(k2, newSize);
                                return(true);
                            }
                            if (k2.Address + i == segmentAddress)
                            {
                                long expandedSegmentSize = i + segmentSize;
                                if (expandedSegmentSize <= int.MaxValue)
                                {
                                    fileGrowthStore[de.Value.Key] = expandedSegmentSize;
                                    //fileGrowthStore.CurrentValue = expandedSegmentSize;
                                    return(true);
                                }
                            }
                        }
                        if (++moveNextCount >= 2)
                        {
                            break;
                        }
                        fileGrowthStore.MoveNext();
                    }
                    fileGrowthStore.Add(key, segmentSize);
                    return(true);
                }
                throw new InvalidOperationException(
                          string.Format("File '{0}' region '{1}' already expanded.", key.Filename, key.Address)
                          );
            }
            finally
            {
                fileGrowthStore.Locker.Unlock();
            }
        }