Esempio n. 1
0
        public void Dispose()
        {
            int size = Length;

            Length = -1;
            if (size > 0)
            {
                lock (SyncRoot) {
                    Allocated -= size;
                    if (size <= MaxSegmentSize)
                    {
                        FreeChunk prev = null;
                        FreeChunk next = Segment.FirstFreeChunk;
                        while (next != null && Index > next.Index)
                        {
                            prev = next;
                            next = next.NextInSegment;
                        }
                        if (prev == null || prev.Index + prev.Size != Index)
                        {
                            if (next != null && Index + size == next.Index)
                            {
                                next.Index = Index;
                                next.Size += size;
                                var nextNext = next.NextInSize;
                                if (nextNext != null && next.Size > nextNext.Size)
                                {
                                    next.MoveAfterSizeHasIncreased();
                                }
                            }
                            else
                            {
                                new FreeChunk(Segment, prev, next, Index, size); // inserts itself into the lists
                            }
                        }
                        else
                        {
                            if (next != null && Index + size == next.Index)
                            {
                                prev.Size += size + next.Size;
                                next.Remove();
                            }
                            else
                            {
                                prev.Size += size;
                            }
                            if (prev.NextInSize != null && prev.Size > prev.NextInSize.Size)
                            {
                                prev.MoveAfterSizeHasIncreased();
                            }
                        }
                        Segment.AssertIntegrity();
                        var first = Segment.FirstFreeChunk;
                        if (first.Size == Segment.Size && ++NumberOfUnusedSegments > MaxNumberOfUnusedSegments)
                        {
                            --NumberOfUnusedSegments;
                            first.Remove();
                            Segment.Dispose();
                        }
                    }
                    else // size > MaxSegmentSize
                    {
                        Debug.Assert(size == Segment.Size);
                        Segment.Dispose();
                    }
                }
            }
        }