Ejemplo n.º 1
0
    private void writeKVStateData() throws IOException, InterruptedException {

      byte[] previousKey = null;
      byte[] previousValue = null;

      List<Tuple2<RocksIterator, Integer>> kvStateIteratorsHandover = this.kvStateIterators;
      this.kvStateIterators = null;

      // Here we transfer ownership of RocksIterators to the RocksDBMergeIterator
      try (RocksDBMergeIterator mergeIterator =
          new RocksDBMergeIterator(kvStateIteratorsHandover, stateBackend.keyGroupPrefixBytes)) {

        // preamble: setup with first key-group as our lookahead
        if (mergeIterator.isValid()) {
          // begin first key-group by recording the offset
          keyGroupRangeOffsets.setKeyGroupOffset(mergeIterator.keyGroup(), outStream.getPos());
          // write the k/v-state id as metadata
          // TODO this could be aware of keyGroupPrefixBytes and write only one byte if possible
          outputView.writeShort(mergeIterator.kvStateId());
          previousKey = mergeIterator.key();
          previousValue = mergeIterator.value();
          mergeIterator.next();
        }

        // main loop: write k/v pairs ordered by (key-group, kv-state), thereby tracking key-group
        // offsets.
        while (mergeIterator.isValid()) {

          assert (!hasMetaDataFollowsFlag(previousKey));

          // set signal in first key byte that meta data will follow in the stream after this k/v
          // pair
          if (mergeIterator.isNewKeyGroup() || mergeIterator.isNewKeyValueState()) {

            // be cooperative and check for interruption from time to time in the hot loop
            checkInterrupted();

            setMetaDataFollowsFlagInKey(previousKey);
          }

          writeKeyValuePair(previousKey, previousValue);

          // write meta data if we have to
          if (mergeIterator.isNewKeyGroup()) {
            // TODO this could be aware of keyGroupPrefixBytes and write only one byte if possible
            outputView.writeShort(END_OF_KEY_GROUP_MARK);
            // begin new key-group
            keyGroupRangeOffsets.setKeyGroupOffset(mergeIterator.keyGroup(), outStream.getPos());
            // write the kev-state
            // TODO this could be aware of keyGroupPrefixBytes and write only one byte if possible
            outputView.writeShort(mergeIterator.kvStateId());
          } else if (mergeIterator.isNewKeyValueState()) {
            // write the k/v-state
            // TODO this could be aware of keyGroupPrefixBytes and write only one byte if possible
            outputView.writeShort(mergeIterator.kvStateId());
          }

          // request next k/v pair
          previousKey = mergeIterator.key();
          previousValue = mergeIterator.value();
          mergeIterator.next();
        }
      }

      // epilogue: write last key-group
      if (previousKey != null) {
        assert (!hasMetaDataFollowsFlag(previousKey));
        setMetaDataFollowsFlagInKey(previousKey);
        writeKeyValuePair(previousKey, previousValue);
        // TODO this could be aware of keyGroupPrefixBytes and write only one byte if possible
        outputView.writeShort(END_OF_KEY_GROUP_MARK);
      }
    }