private void writeSearchResults(IFrameTupleAccessor leftAccessor, int tIndex) throws Exception {
    while (cursor.hasNext()) {
      tb.reset();
      cursor.next();

      ITupleReference frameTuple = cursor.getTuple();
      for (int i = 0; i < inputRecDesc.getFields().length; i++) {
        int tupleStart = leftAccessor.getTupleStartOffset(tIndex);
        int fieldStart = leftAccessor.getFieldStartOffset(tIndex, i);
        int offset = leftAccessor.getFieldSlotsLength() + tupleStart + fieldStart;
        int len = leftAccessor.getFieldEndOffset(tIndex, i) - fieldStart;
        dos.write(leftAccessor.getBuffer().array(), offset, len);
        tb.addFieldEndOffset();
      }
      for (int i = 0; i < frameTuple.getFieldCount(); i++) {
        dos.write(
            frameTuple.getFieldData(i), frameTuple.getFieldStart(i), frameTuple.getFieldLength(i));
        tb.addFieldEndOffset();
      }

      if (!appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize())) {
        FrameUtils.flushFrame(writeBuffer, writer);
        appender.reset(writeBuffer, true);
        if (!appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize())) {
          throw new IllegalStateException();
        }
      }
    }
  }
 @Override
 public void close() throws HyracksDataException {
   try {
     if (appender.getTupleCount() > 0) {
       FrameUtils.flushFrame(writeBuffer, writer);
     }
     writer.close();
     try {
       cursor.close();
     } catch (Exception e) {
       throw new HyracksDataException(e);
     }
   } finally {
     treeIndexOpHelper.close();
   }
 }
  /** write the right result */
  private void writeRightResults(ITupleReference frameTuple) throws Exception {
    tb.reset();
    for (int i = 0; i < frameTuple.getFieldCount(); i++) {
      dos.write(
          frameTuple.getFieldData(i), frameTuple.getFieldStart(i), frameTuple.getFieldLength(i));
      tb.addFieldEndOffset();
    }

    if (!appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize())) {
      FrameUtils.flushFrame(writeBuffer, writer);
      appender.reset(writeBuffer, true);
      if (!appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize())) {
        throw new IllegalStateException();
      }
    }
  }
  /** write the left result */
  private void writeLeftResults(IFrameTupleAccessor leftAccessor, int tIndex) throws Exception {
    tb.reset();
    for (int i = 0; i < inputRecDesc.getFields().length; i++) {
      int tupleStart = leftAccessor.getTupleStartOffset(tIndex);
      int fieldStart = leftAccessor.getFieldStartOffset(tIndex, i);
      int offset = leftAccessor.getFieldSlotsLength() + tupleStart + fieldStart;
      int len = leftAccessor.getFieldEndOffset(tIndex, i) - fieldStart;
      dos.write(leftAccessor.getBuffer().array(), offset, len);
      tb.addFieldEndOffset();
    }

    if (!appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize())) {
      FrameUtils.flushFrame(writeBuffer, writer);
      appender.reset(writeBuffer, true);
      if (!appender.append(tb.getFieldEndOffsets(), tb.getByteArray(), 0, tb.getSize())) {
        throw new IllegalStateException();
      }
    }
  }