Пример #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 void AddToTransCache(Collections.Generic.ISortedDictionary <long, long> store,
                              long dataAddress, long dataSize, int segmentSize)
 {
     if (store.Count == 0)
     {
         store.Add(dataAddress, dataSize);
     }
     else if (!DetectAndMerge(store, dataAddress, dataSize, segmentSize))
     {
         store.Add(dataAddress, dataSize);
     }
 }
Пример #4
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();
            }
        }
Пример #5
0
        internal static bool DetectAndMerge(Collections.Generic.ISortedDictionary <long, long> store,
                                            long dataAddress, long dataSize, int segmentSize = DataBlock.DataBlockDriver.MaxSegmentSize, RegionLogic region = null)
        {
            if (store.Count == 0)
            {
                if (dataSize > segmentSize)
                {
                    return(false);
                }
                store.Add(dataAddress, dataSize);
                return(true);
            }
            if (store.Search(dataAddress))
            {
                long currSize = store.CurrentValue;
                if (currSize < dataSize)
                {
                    store.CurrentValue = dataSize;
                }
                return(true);
            }
            //** Detect and merge contiguous deleted blocks
            short passCount = 0;

            if (!store.MovePrevious())
            {
                store.MoveFirst();
            }
            while (true)
            {
                KeyValuePair <long, long>?item = store.CurrentEntry;
                long k2 = item.Value.Key;
                long i  = 0;
                long cv = store.CurrentValue;
                i = cv;
                if (region != null)
                {
                    if (region.Equals(dataAddress, dataSize, k2, i) ||
                        region.FirstWithinSecond(dataAddress, dataSize, k2, i))
                    {
                        return(true);
                    }
                    if (region.FirstWithinSecond(k2, i, dataAddress, dataSize))
                    {
                        store.Remove(k2);
                        store.Add(dataAddress, dataSize);
                        return(true);
                    }
                }
                if (dataAddress + dataSize == k2)
                {
                    long newSize = i + dataSize;
                    if (newSize <= segmentSize)
                    {
                        store.Remove(item.Value.Key);
                        store.Add(dataAddress, newSize);
                        return(true);
                    }
                    return(false);
                }
                if (k2 + i == dataAddress)
                {
                    if (i + dataSize <= segmentSize)
                    {
                        store.CurrentValue = i + dataSize;
                        return(true);
                    }
                    return(false);
                }
                if (++passCount >= 2)
                {
                    break;
                }
                if (!store.MoveNext())
                {
                    break;
                }
            }
            return(false);
        }