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(); }
public int getRatingDataSize() { return getRatingCount() * format.getRatingSize(); }