docs: public void truncateToSequenceNumber(final long truncationSeqNo) throws IOException {
          assert(m_memoryDeque.isEmpty());
          m_persistentDeque.parseAndTruncate(new BinaryDequeTruncator() {
  
              @Override
              public TruncatorResponse parse(BBContainer bbc) {
                  ByteBuffer b = bbc.b();
                  ByteOrder endianness = b.order();
                  b.order(ByteOrder.LITTLE_ENDIAN);
                  try {
                      final long startSequenceNumber = b.getLong();
                      // If after the truncation point is the first row in the block, the entire block is to be discarded
                      if (startSequenceNumber > truncationSeqNo) {
                          return PersistentBinaryDeque.fullTruncateResponse();
                      }
                      final long committedSequenceNumber = b.getLong(); // committedSequenceNumber
                      final int tupleCountPos = b.position();
                      final int tupleCount = b.getInt();
                      // There is nothing to do with this buffer
                      final long lastSequenceNumber = startSequenceNumber + tupleCount - 1;
                      if (lastSequenceNumber <= truncationSeqNo) {
                          return null;
                      }
                      b.getLong(); // uniqueId
  
                      // Partial truncation
                      int offset = 0;
                      while (b.hasRemaining()) {
                          if (startSequenceNumber + offset > truncationSeqNo) {
                              // The sequence number of this row is the greater than the truncation sequence number.
                              // Don't want this row, but want to preserve all rows before it.
                              // Move back before the row length prefix, txnId and header
                              // Return everything in the block before the truncation point.
                              // Indicate this is the end of the interesting data.
                              b.limit(b.position());
                              // update tuple count in the header
                              b.putInt(tupleCountPos, offset - 1);
                              b.position(0);
                              return new ByteBufferTruncatorResponse(b);
                          }
                          offset++;
                          // Not the row we are looking to truncate at. Skip past it (row length + row length field).
                          final int rowLength = b.getInt();
                          b.position(b.position() + rowLength);
                      }
                      return null;
                  } finally {
                      b.order(endianness);
                  }
              }
          });
  
          // close reopen reader
          m_persistentDeque.close();
          CatalogContext catalogContext = VoltDB.instance().getCatalogContext();
          Table streamTable = VoltDB.instance().getCatalogContext().database.getTables().get(m_streamName);
          StreamTableSchemaSerializer ds = new StreamTableSchemaSerializer(
                  streamTable, m_streamName, catalogContext.m_genId);
          m_persistentDeque = new PersistentBinaryDeque(m_nonce, ds, new VoltFile(m_path), exportLog,
                  !DISABLE_COMPRESSION);
          m_reader = m_persistentDeque.openForRead(m_nonce);
          // temporary debug stmt
          exportLog.info("After truncate, PBD size is " + (m_reader.sizeInBytes() - (8 * m_reader.getNumObjects())));
      }