Пример #1
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();
            }
        }