public char[] increaseFreeSpace(/*int size*/ char[] buffer) { int size = buffer.length; // double size of buffer // increase buffer buffer = Arrays.copyOf(buffer, buffer.length * 2); // actual suspended location if (suspendedLength > 0) { int suspendedOffset = suspendedSegments.peekLast().start; // move suspended data to the end of the buffer System.arraycopy( buffer, suspendedOffset, buffer, buffer.length - suspendedLength, suspendedLength); } this.freeLength += size; this.size += size; for (Iterator<Segment<T>> it = suspendedSegments.iterator(); it.hasNext(); ) { Segment<T> segment = it.next(); segment.start += size; } return buffer; }
static <T> Segment<T> newSegment(T source, int start, int length) { Segment segment = new Segment(); segment.source = source; segment.start = start; segment.length = length; return segment; }
public void reset(int pos, char[] buffer) { if (pos < 0 && activeSegments.size() == 1) { return; } while (true) { Segment<T> lastActiveSegment = activeSegments.peekLast(); if (pos < lastActiveSegment.start - 1) { // segment is removed if root, and last suspended segment is merged // with last active segment if it is the same source if (lastActiveSegment.root) { activeSegments.removeLast(); activeLength -= lastActiveSegment.length; freeLength += lastActiveSegment.length; lastActiveSegment = activeSegments.peekLast(); Segment<T> lastSuspendedSegment = suspendedSegments.peekLast(); if (lastSuspendedSegment != null && lastSuspendedSegment.source.equals(lastActiveSegment.source)) { lastActiveSegment.length += lastSuspendedSegment.length; // move data in buffer : suspended space -> active space System.arraycopy( buffer, lastSuspendedSegment.start, buffer, activeLength, lastSuspendedSegment.length); suspendedSegments.removeLast(); activeLength += lastSuspendedSegment.length; suspendedLength -= lastSuspendedSegment.length; } continue; } // segment is suspended if not root activeSegments.removeLast(); suspendedSegments.addLast(lastActiveSegment); int startInSuspendedSpace = size - suspendedLength - lastActiveSegment.length; // move data in buffer : active space -> suspended space System.arraycopy( buffer, lastActiveSegment.start, buffer, startInSuspendedSpace, lastActiveSegment.length); lastActiveSegment.start = startInSuspendedSpace; activeLength -= lastActiveSegment.length; suspendedLength += lastActiveSegment.length; } else { break; } } }
public void restoreLastSuspendedSegment(int position, char[] buffer) { Segment<T> lastSuspendedSegment = suspendedSegments.pollLast(); if (lastSuspendedSegment != null) { System.arraycopy( buffer, lastSuspendedSegment.start, buffer, activeLength, lastSuspendedSegment.length); activeSegments.add(lastSuspendedSegment); lastSuspendedSegment.start = activeLength; activeLength += lastSuspendedSegment.length; suspendedLength -= lastSuspendedSegment.length; } }
public void consume(int size) { this.activeLength -= size; this.freeLength += size; // remove from active segments int removed = 0; for (Iterator<Segment<T>> it = activeSegments.iterator(); it.hasNext(); ) { Segment<T> segment = it.next(); int remaining = size - removed; int sizeToRemove = Math.min(remaining, segment.length); segment.length -= sizeToRemove; segment.start -= removed; removed += sizeToRemove; if (segment.length == 0 && activeSegments.size() > 1) { it.remove(); } } }