/** * Helper method for reusing a segment from free-segments list. * Caller must guarantee there is such a segment available; this is * done in advance to achieve atomicity of multi-segment-allocation. */ protected final S _reuseFree() { S freeSeg = _firstFreeSegment; if (freeSeg == null) { // sanity check throw new IllegalStateException("Internal error: no free segments available"); } //int oldCount = count(_firstFreeSegment); _firstFreeSegment = freeSeg.getNext(); --_freeSegmentCount; _head = freeSeg; ++_usedSegmentsCount; // optional sanity check, if we are tracking hard-to-find bugs... /* int count = count(_firstFreeSegment); System.err.print("[r="+oldCount+"->"+_freeSegmentCount+"(c="+count+")/u="+_usedSegmentsCount+"]"); if (count != _freeSegmentCount) { System.err.println("ERROR: free seg "+_freeSegmentCount+"; but saw "+count+" actual!"); } */ return freeSeg; }
/** * Helper method for reusing a segment from free-segments list. * Caller must guarantee there is such a segment available; this is * done in advance to achieve atomicity of multi-segment-allocation. */ protected final S _reuseFree() { S freeSeg = _firstFreeSegment; if (freeSeg == null) { // sanity check throw new IllegalStateException("Internal error: no free segments available"); } //int oldCount = count(_firstFreeSegment); _firstFreeSegment = freeSeg.getNext(); --_freeSegmentCount; _head = freeSeg; ++_usedSegmentsCount; // optional sanity check, if we are tracking hard-to-find bugs... /* int count = count(_firstFreeSegment); System.err.print("[r="+oldCount+"->"+_freeSegmentCount+"(c="+count+")/u="+_usedSegmentsCount+"]"); if (count != _freeSegmentCount) { System.err.println("ERROR: free seg "+_freeSegmentCount+"; but saw "+count+" actual!"); } */ return freeSeg; }
@Override // from Closeable -- note, does NOT throw IOException public synchronized final void close() { // first do regular cleanup clear(); // then free the head/tail node as well _usedSegmentsCount = 0; // 24-Apr-2013, tatu: As per #16, must ensure proper cleaning if (_head != null) { _head.markFree(); _segmentAllocator.releaseSegment(_head); _head = _tail = null; } // and any locally recycled buffers as well S seg = _firstFreeSegment; _firstFreeSegment = null; _freeSegmentCount = 0; while (seg != null) { S next = seg.getNext(); _segmentAllocator.releaseSegment(seg); seg = next; } // one more thing: wake up thread(s) that are blocked (if any) this.notifyAll(); }
@Override // from Closeable -- note, does NOT throw IOException public synchronized final void close() { // first do regular cleanup clear(); // then free the head/tail node as well _usedSegmentsCount = 0; // 24-Apr-2013, tatu: As per #16, must ensure proper cleaning if (_head != null) { _head.markFree(); _segmentAllocator.releaseSegment(_head); _head = _tail = null; } // and any locally recycled buffers as well S seg = _firstFreeSegment; _firstFreeSegment = null; _freeSegmentCount = 0; while (seg != null) { S next = seg.getNext(); _segmentAllocator.releaseSegment(seg); seg = next; } // one more thing: wake up thread(s) that are blocked (if any) this.notifyAll(); }
protected MemBufferBase(SegmentAllocator<S> allocator, int minSegmentsToAllocate, int maxSegmentsToAllocate, S initialSegments) { _segmentAllocator = allocator; _segmentSize = allocator.getSegmentSize(); _maxSegmentsForReuse = minSegmentsToAllocate; _maxSegmentsToAllocate = maxSegmentsToAllocate; // all but one of segments goes to the free list _firstFreeSegment = initialSegments.getNext(); // and first one is used as both head and tail initialSegments.relink(null); _head = _tail = initialSegments; // also, better initialize initial segment for writing and reading _head.initForWriting(); _head.initForReading(); _usedSegmentsCount = 1; // Sanity checks? if yes, uncomment this... /* int count = count(_firstFreeSegment); if (count != _freeSegmentCount) { throw new IllegalStateException("Bad initial _freeSegmentCount ("+_freeSegmentCount+"): but only got "+count+" linked"); } */ _freeSegmentCount = minSegmentsToAllocate-1; }
protected MemBufferBase(SegmentAllocator<S> allocator, int minSegmentsToAllocate, int maxSegmentsToAllocate, S initialSegments) { _segmentAllocator = allocator; _segmentSize = allocator.getSegmentSize(); _maxSegmentsForReuse = minSegmentsToAllocate; _maxSegmentsToAllocate = maxSegmentsToAllocate; // all but one of segments goes to the free list _firstFreeSegment = initialSegments.getNext(); // and first one is used as both head and tail initialSegments.relink(null); _head = _tail = initialSegments; // also, better initialize initial segment for writing and reading _head.initForWriting(); _head.initForReading(); _usedSegmentsCount = 1; // Sanity checks? if yes, uncomment this... /* int count = count(_firstFreeSegment); if (count != _freeSegmentCount) { throw new IllegalStateException("Bad initial _freeSegmentCount ("+_freeSegmentCount+"): but only got "+count+" linked"); } */ _freeSegmentCount = minSegmentsToAllocate-1; }