public StreamRequestHandlerState handleRequest(
      DataInputStream inputStream, DataOutputStream outputStream) throws IOException {
    if (!keyIterator.hasNext()) return StreamRequestHandlerState.COMPLETE;

    long startNs = System.nanoTime();
    ByteArray key = keyIterator.next();
    stats.recordDiskTime(handle, System.nanoTime() - startNs);

    throttler.maybeThrottle(key.length());
    if (validPartition(key.get()) && filter.accept(key, null) && counter % skipRecords == 0) {
      VAdminProto.FetchPartitionEntriesResponse.Builder response =
          VAdminProto.FetchPartitionEntriesResponse.newBuilder();
      response.setKey(ProtoUtils.encodeBytes(key));

      fetched++;
      handle.incrementEntriesScanned();
      Message message = response.build();

      startNs = System.nanoTime();
      ProtoUtils.writeMessage(outputStream, message);
      stats.recordNetworkTime(handle, System.nanoTime() - startNs);
    }

    // log progress
    counter++;

    if (0 == counter % 100000) {
      long totalTime = (System.currentTimeMillis() - startTime) / 1000;

      if (logger.isDebugEnabled())
        logger.debug(
            "fetchKeys() scanned "
                + counter
                + " keys, fetched "
                + fetched
                + " keys for store:"
                + storageEngine.getName()
                + " partition:"
                + partitionList
                + " in "
                + totalTime
                + " s");
    }

    if (keyIterator.hasNext()) return StreamRequestHandlerState.WRITING;
    else {
      stats.closeHandle(handle);
      return StreamRequestHandlerState.COMPLETE;
    }
  }
  public StreamRequestHandler handleRequest(
      DataInputStream inputStream, DataOutputStream outputStream) throws IOException {
    VoldemortRequest.Builder request =
        ProtoUtils.readToBuilder(inputStream, VoldemortRequest.newBuilder());
    boolean shouldRoute = request.getShouldRoute();
    RequestRoutingType type = RequestRoutingType.getRequestRoutingType(shouldRoute, false);

    if (request.hasRequestRouteType()) {
      type = RequestRoutingType.getRequestRoutingType(request.getRequestRouteType());
    }

    String storeName = request.getStore();
    Store<ByteArray, byte[]> store = getStore(storeName, type);
    Message response;
    if (store == null) {
      response = unknownStore(storeName, request.getType());
    } else {
      switch (request.getType()) {
        case GET:
          response = handleGet(request.getGet(), store);
          break;
        case GET_ALL:
          response = handleGetAll(request.getGetAll(), store);
          break;
        case PUT:
          response = handlePut(request.getPut(), store);
          break;
        case DELETE:
          response = handleDelete(request.getDelete(), store);
          break;
        case GET_VERSION:
          response = handleGetVersion(request.getGet(), store);
          break;
        default:
          throw new VoldemortException("Unknown operation " + request.getType());
      }
    }
    ProtoUtils.writeMessage(outputStream, response);
    return null;
  }
  public StreamRequestHandler handleRequest(
      final DataInputStream inputStream, final DataOutputStream outputStream) throws IOException {
    // Another protocol buffers bug here, temp. work around
    VoldemortAdminRequest.Builder request = VoldemortAdminRequest.newBuilder();
    int size = inputStream.readInt();

    if (logger.isTraceEnabled())
      logger.trace("In handleRequest, request specified size of " + size + " bytes");

    if (size < 0)
      throw new IOException("In handleRequest, request specified size of " + size + " bytes");

    byte[] input = new byte[size];
    ByteUtils.read(inputStream, input);
    request.mergeFrom(input);

    switch (request.getType()) {
      case GET_METADATA:
        ProtoUtils.writeMessage(outputStream, handleGetMetadata(request.getGetMetadata()));
        break;
      case UPDATE_METADATA:
        ProtoUtils.writeMessage(outputStream, handleUpdateMetadata(request.getUpdateMetadata()));
        break;
      case DELETE_PARTITION_ENTRIES:
        ProtoUtils.writeMessage(
            outputStream, handleDeletePartitionEntries(request.getDeletePartitionEntries()));
        break;
      case FETCH_PARTITION_ENTRIES:
        return handleFetchPartitionEntries(request.getFetchPartitionEntries());

      case UPDATE_PARTITION_ENTRIES:
        return handleUpdatePartitionEntries(request.getUpdatePartitionEntries());

      case INITIATE_FETCH_AND_UPDATE:
        ProtoUtils.writeMessage(
            outputStream, handleFetchAndUpdate(request.getInitiateFetchAndUpdate()));
        break;
      case ASYNC_OPERATION_STATUS:
        ProtoUtils.writeMessage(outputStream, handleAsyncStatus(request.getAsyncOperationStatus()));
        break;
      case INITIATE_REBALANCE_NODE:
        ProtoUtils.writeMessage(
            outputStream, handleRebalanceNode(request.getInitiateRebalanceNode()));
        break;
      case ASYNC_OPERATION_LIST:
        ProtoUtils.writeMessage(
            outputStream, handleAsyncOperationList(request.getAsyncOperationList()));
        break;
      case ASYNC_OPERATION_STOP:
        ProtoUtils.writeMessage(
            outputStream, handleAsyncOperationStop(request.getAsyncOperationStop()));
        break;
      case TRUNCATE_ENTRIES:
        ProtoUtils.writeMessage(outputStream, handleTruncateEntries(request.getTruncateEntries()));
        break;
      case ADD_STORE:
        ProtoUtils.writeMessage(outputStream, handleAddStore(request.getAddStore()));
        break;
      default:
        throw new VoldemortException("Unkown operation " + request.getType());
    }

    return null;
  }