예제 #1
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();
     }
 }
예제 #2
0
        //public Region RemoveIntersections(Collections.Generic.ISortedDictionary<Transaction.Transaction.RecordKey, long> addStore,
        //    Transaction.Transaction.RecordKey key, Region region)
        //{
        //    Region target = new List<KeyValuePair<RecordKey, Region>>();
        //    foreach(var area in region)
        //    {

        //    }
        //}

        /// <summary>
        /// RemoveIntersections will check whether an area on disk was already
        /// inclusive in any of the segment areas stored as entries in a store (addStore).
        /// If input area is fully inclusive, this function returns null, otherwise
        /// it will return a region equivalent to the input area minus any intersecting
        /// area(s) of segment(s) in the store.
        /// </summary>
        /// <param name="addStore"></param>
        /// <param name="key"></param>
        /// <param name="blockAddress"></param>
        /// <param name="segmentSize"></param>
        /// <returns></returns>
        public Region RemoveIntersections(
            Collections.Generic.ISortedDictionary <Transaction.Transaction.RecordKey, long> addStore,
            Transaction.Transaction.RecordKey key,
            long blockAddress, int segmentSize)
        {
            addStore.Locker.Lock();
            try
            {
                long size;
                if (addStore.TryGetValue(key, out size))
                {
                    if (size >= segmentSize)
                    {
                        return(null);
                    }
                }
                else if (!addStore.MovePrevious())
                {
                    addStore.MoveFirst();
                }

                //** Step 1
                //** Starting from current block until block whose address is > BlockAddress + SegmentSize...
                //** long[0] = Address
                //** long[1] = Size
                var region = new Region(blockAddress, segmentSize);
                Transaction.Transaction.RecordKey k2;
                short passCount = 0;
                while (!addStore.EndOfTree())
                {
                    var de = addStore.CurrentEntry;
                    k2 = de.Value.Key;
                    if (k2.ServerSystemFilename == key.ServerSystemFilename &&
                        k2.Filename == key.Filename)
                    // && k2.CollectionName == key.CollectionName)
                    {
                        size = de.Value.Value;
                        if (k2.Address >= blockAddress + segmentSize)
                        {
                            break;
                        }
                        if (size > int.MaxValue)
                        {
                            throw new InvalidOperationException(
                                      string.Format(
                                          "Updated segment Size({0} reached > int.MaxValue which isn't supported in a transaction. Keep your transaction smaller by Committing more often",
                                          size));
                        }
                        if (Intersect(k2.Address, (int)size, blockAddress, segmentSize))
                        {
                            region.Subtract(k2.Address, (int)size);
                            if (region.Count == 0)
                            {
                                return(null);
                            }
                        }
                        else if (++passCount >= 2)
                        {
                            break;
                        }
                    }
                    else if (++passCount >= 2)
                    {
                        break;
                    }
                    if (!addStore.MoveNext())
                    {
                        break;
                    }
                }
                return(region);
            }
            finally
            {
                addStore.Locker.Unlock();
            }
        }