@Test
  public void simpleWriteRead() {

    byte primaryRingSizeInBits = 9;
    byte byteRingSizeInBits = 18;

    Pipe ring = new Pipe(new PipeConfig(primaryRingSizeInBits, byteRingSizeInBits, null, FROM));
    ring.initBuffers();

    int messageSize = FROM.fragDataSize[FRAG_LOC];

    int varDataMax = (ring.byteMask / (ring.mask >> 1)) / messageSize;
    int testSize = ((1 << primaryRingSizeInBits) / messageSize) - 1; // room for EOF

    writeTestValue(ring, varDataMax, testSize);

    // now read the data back
    int FIELD_LOC =
        FieldReferenceOffsetManager.lookupFieldLocator(SINGLE_MESSAGE_NAMES[0], FRAG_LOC, FROM);

    int k = testSize;
    while (PipeReader.tryReadFragment(ring)) {

      --k;
      assertTrue(PipeReader.isNewMessage(ring));
      int messageIdx = PipeReader.getMsgIdx(ring);
      if (messageIdx < 0) {
        return;
      }
      testReadValue(ring, varDataMax, testSize, FIELD_LOC, k, messageIdx);
    }
  }
  private void writeTestValue(Pipe ring, int blockSize, int testSize) {

    int FIELD_LOC =
        FieldReferenceOffsetManager.lookupFieldLocator(SINGLE_MESSAGE_NAMES[0], FRAG_LOC, FROM);
    assertTrue(0 == Pipe.contentRemaining(ring));
    int j = testSize;
    while (true) {

      if (j == 0) {
        PipeWriter.publishEOF(ring);
        return; // done
      }

      if (PipeWriter.tryWriteFragment(
          ring, FRAG_LOC)) { // returns true if there is room to write this fragment

        int value = (--j * blockSize) / testSize;
        PipeWriter.writeFloatAsIntBits(ring, FIELD_LOC, 1f / (float) value);
        PipeWriter.publishWrites(ring); // must always publish the writes if message or fragment

      } else {
        // Unable to write because there is no room so do something else while we are waiting.
        Thread.yield();
      }
    }
  }
  public OutputPipeInvocationHandler(Pipe outputRing, int msgIdx, Class<?> clazz) {
    super(clazz.getMethods());

    FieldReferenceOffsetManager from = Pipe.from(outputRing);
    final Method[] methods = clazz.getMethods();

    writers = new OutputPipeWriterMethod[MAX_METHODS];
    int j = methods.length;
    while (--j >= 0) {
      final Method method = methods[j];
      ProngTemplateField fieldAnnonation = method.getAnnotation(ProngTemplateField.class);
      if (null != fieldAnnonation) {

        int fieldLoc =
            FieldReferenceOffsetManager.lookupFieldLocator(fieldAnnonation.fieldId(), msgIdx, from);

        int key = buildKey(this, method.getName());
        if (null != writers[key]) {
          throw new UnsupportedOperationException();
        }
        writers[key] =
            OutputPipeWriterMethod.buildWriteForYourType(
                outputRing,
                fieldAnnonation.decimalPlaces(),
                fieldLoc,
                (fieldLoc >> FieldReferenceOffsetManager.RW_FIELD_OFF_BITS)
                    & TokenBuilder.MASK_TYPE,
                from);
      }
    }
  }
  @Test
  public void simpleWriteReadThreaded() {

    final byte primaryRingSizeInBits = 7; // this ring is 2^7 eg 128
    final byte byteRingSizeInBits = 16;
    final Pipe ring =
        new Pipe(new PipeConfig(primaryRingSizeInBits, byteRingSizeInBits, null, FROM));
    ring.initBuffers();

    final int messageSize = FROM.fragDataSize[FRAG_LOC];

    final int varDataMax = (ring.byteMask / (ring.mask >> 1)) / messageSize;
    final int testSize = (1 << primaryRingSizeInBits) / messageSize;

    Thread t =
        new Thread(
            new Runnable() {

              @Override
              public void run() {
                writeTestValue(ring, varDataMax, testSize);
              }
            });
    t.start();

    // now read the data back

    int FIELD_LOC =
        FieldReferenceOffsetManager.lookupFieldLocator(SINGLE_MESSAGE_NAMES[0], FRAG_LOC, FROM);

    int k = testSize;
    while (k > 0) {

      // This is the example code that one would normally use.

      // System.err.println("content "+ring.contentRemaining(ring));
      if (PipeReader.tryReadFragment(
          ring)) { // this method releases old messages as needed and moves pointer up to the next
        // fragment
        k--; // count down all the expected messages so we stop this test at the right time

        assertTrue(PipeReader.isNewMessage(ring));
        int messageIdx = PipeReader.getMsgIdx(ring);
        if (messageIdx < 0) {
          return;
        }
        testReadValue(ring, varDataMax, testSize, FIELD_LOC, k, messageIdx);

      } else {
        // unable to read so at this point
        // we can do other work and try again soon
        Thread.yield();
      }
    }
  }