private void upgradeRatings(BinaryFormat newFormat) throws IOException {
    Preconditions.checkArgument(
        newFormat.getRatingSize() > format.getRatingSize(), "new format is not wider than old");
    logger.info("upgrading {} ratings from {} to {}", index, format, newFormat);

    ByteBuffer oldBuffer = ByteBuffer.allocateDirect(format.getRatingSize());
    ByteBuffer newBuffer = ByteBuffer.allocateDirect(newFormat.getRatingSize());
    MutableRating scratch = new MutableRating();

    long oldPos = BinaryHeader.HEADER_SIZE + index * format.getRatingSize();
    Preconditions.checkState(channel.position() == oldPos, "channel is at the wrong position");
    long newPos = BinaryHeader.HEADER_SIZE + index * newFormat.getRatingSize();
    channel.position(newPos);
    // loop backwards, coping each rating to later in the file
    for (int i = index - 1; i >= 0; i--) {
      oldPos -= format.getRatingSize();
      newPos -= newFormat.getRatingSize();

      // read the old rating
      BinaryUtils.readBuffer(channel, oldBuffer, oldPos);
      oldBuffer.flip();
      format.readRating(oldBuffer, scratch);
      oldBuffer.clear();

      // write the new rating
      newFormat.renderRating(scratch, newBuffer);
      newBuffer.flip();
      BinaryUtils.writeBuffer(channel, newBuffer, newPos);
      newBuffer.clear();
    }
    assert oldPos == BinaryHeader.HEADER_SIZE;
    assert newPos == BinaryHeader.HEADER_SIZE;
    format = newFormat;
    ratingBuffer = ByteBuffer.allocateDirect(newFormat.getRatingSize());
  }
  /**
   * Create a new binary rating packer.
   *
   * @param file The output file.
   * @throws IOException The output exception.
   */
  BinaryRatingPacker(File file, EnumSet<BinaryFormatFlag> flags) throws IOException {
    format = BinaryFormat.createWithFlags(PackHeaderFlag.fromFormatFlags(flags));
    outputFile = file;

    logger.debug("opening binary pack file {}", outputFile);
    output = new RandomAccessFile(file, "rw");
    channel = output.getChannel();

    userMap = new Long2ObjectOpenHashMap<IntList>();
    itemMap = new Long2ObjectOpenHashMap<IntList>();

    lastTimestamp = Long.MIN_VALUE;
    needsSorting = false;
    index = 0;

    // skip the header
    channel.position(BinaryHeader.HEADER_SIZE);

    ratingBuffer = ByteBuffer.allocateDirect(format.getRatingSize());
  }
 private long ratingPos(int idx) {
   long offset = format.getHeaderSize();
   return offset + idx * format.getRatingSize();
 }
Exemple #4
0
 public int getRatingDataSize() {
   return getRatingCount() * format.getRatingSize();
 }