// single pass attempt to copy if any can not accept the data then they are skipped // and true will be returned instead of false. private static boolean doingCopy( TapeWriteStage ss, int byteTailPos, int primaryTailPos, int totalPrimaryCopy, int totalBytesCopy) { IntBuffer primaryInts = RingBuffer.wrappedStructuredLayoutRingBuffer(ss.source); ByteBuffer secondaryBytes = RingBuffer.wrappedUnstructuredLayoutRingBufferA(ss.source); primaryInts.position(primaryTailPos); primaryInts.limit( primaryTailPos + totalPrimaryCopy); // TODO: AA, this will not work on the wrap, we must mask and do // muliple copies secondaryBytes.position(byteTailPos); secondaryBytes.limit(byteTailPos + totalBytesCopy); ss.header.clear(); ss.headerAsInts.put(totalBytesCopy + (totalPrimaryCopy << 2)); ss.headerAsInts.put(totalPrimaryCopy << 2); // TODO: must return false if there is no room to write. // TODO: BB, this creates a bit of garbage for the map, perhaps we should map larger blocks // expecting to use them for multiple writes. MappedByteBuffer mapped; try { mapped = ss.fileChannel.map( MapMode.READ_WRITE, ss.fileChannel.position(), 8 + totalBytesCopy + (totalPrimaryCopy << 2)); mapped.put(ss.header); IntBuffer asIntBuffer = mapped.asIntBuffer(); asIntBuffer.position(2); asIntBuffer.put(primaryInts); mapped.position(mapped.position() + (totalPrimaryCopy << 2)); mapped.put(secondaryBytes); } catch (IOException e) { throw new RuntimeException(e); } return true; }
private static boolean processAvailData(TapeWriteStage ss) { int byteHeadPos; long headPos; // get the new head position byteHeadPos = RingBuffer.bytesHeadPosition(ss.source); headPos = RingBuffer.headPosition(ss.source); while (byteHeadPos != RingBuffer.bytesHeadPosition(ss.source) || headPos != RingBuffer.headPosition(ss.source)) { byteHeadPos = RingBuffer.bytesHeadPosition(ss.source); headPos = RingBuffer.headPosition(ss.source); } // we have established the point that we can read up to, this value is changed by the writer on // the other side // get the start and stop locations for the copy // now find the point to start reading from, this is moved forward with each new read. int pMask = ss.source.mask; long tempTail = RingBuffer.tailPosition(ss.source); int primaryTailPos = pMask & (int) tempTail; long totalPrimaryCopy = (headPos - tempTail); if (totalPrimaryCopy <= 0) { assert (totalPrimaryCopy == 0); return false; // nothing to copy so come back later } int bMask = ss.source.byteMask; int tempByteTail = RingBuffer.bytesTailPosition(ss.source); int byteTailPos = bMask & tempByteTail; int totalBytesCopy = (bMask & byteHeadPos) - byteTailPos; if (totalBytesCopy < 0) { totalBytesCopy += (bMask + 1); } // now do the copies if (doingCopy(ss, byteTailPos, primaryTailPos, (int) totalPrimaryCopy, totalBytesCopy)) { // TODO: play back file with those cunks into indexer to do it after the fact // release tail so data can be written int i = RingBuffer.BYTES_WRAP_MASK & (tempByteTail + totalBytesCopy); RingBuffer.setBytesWorkingTail(ss.source, i); RingBuffer.setBytesTail(ss.source, i); RingBuffer.publishWorkingTailPosition(ss.source, tempTail + totalPrimaryCopy); return true; } return false; // finished all the copy for now }
public String toString() { return getClass().getSimpleName() + (-2 == moreToCopy ? " not running " : " moreToCopy:" + moreToCopy) + " source content " + RingBuffer.contentRemaining(source); }