Пример #1
0
        /// <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)
        {
            if (addStore.Search(key))
            {
                long size = (long)addStore.CurrentValue;
                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)
                {
                    long 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);
        }
Пример #2
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);
        }