@Override
  public void readFields(DataInput in) throws IOException {
    int flags = in.readByte();
    Preconditions.checkArgument(
        flags >> NUM_FLAGS == 0, "Unknown flags set: %d", Integer.toString(flags, 2));
    boolean dense = (flags & FLAG_DENSE) != 0;
    boolean sequential = (flags & FLAG_SEQUENTIAL) != 0;
    boolean named = (flags & FLAG_NAMED) != 0;
    boolean laxPrecision = (flags & FLAG_LAX_PRECISION) != 0;

    int size = Varint.readUnsignedVarInt(in);
    Vector v;
    if (dense) {
      double[] values = new double[size];
      for (int i = 0; i < size; i++) {
        values[i] = laxPrecision ? in.readFloat() : in.readDouble();
      }
      v = new DenseVector(values);
    } else {
      int numNonDefaultElements = Varint.readUnsignedVarInt(in);
      v =
          sequential
              ? new SequentialAccessSparseVector(size, numNonDefaultElements)
              : new RandomAccessSparseVector(size, numNonDefaultElements);
      if (sequential) {
        int lastIndex = 0;
        for (int i = 0; i < numNonDefaultElements; i++) {
          int delta = Varint.readUnsignedVarInt(in);
          int index = lastIndex + delta;
          lastIndex = index;
          double value = laxPrecision ? in.readFloat() : in.readDouble();
          v.setQuick(index, value);
        }
      } else {
        for (int i = 0; i < numNonDefaultElements; i++) {
          int index = Varint.readUnsignedVarInt(in);
          double value = laxPrecision ? in.readFloat() : in.readDouble();
          v.setQuick(index, value);
        }
      }
    }
    if (named) {
      String name = in.readUTF();
      v = new NamedVector(v, name);
    }
    vector = v;
  }
  @Before
  public void setup() {
    // input
    int userID = 1;

    inputPreferences = new ArrayList<VectorWritable>();

    Vector v1 = new RandomAccessSparseVector(Integer.MAX_VALUE, 1);
    Vector v2 = new RandomAccessSparseVector(Integer.MAX_VALUE, 1);

    v1.setQuick(5, 1.0);
    v2.setQuick(6, -1.0);

    inputPreferences.add(new VectorWritable(v1, true));
    inputPreferences.add(new VectorWritable(v2, true));

    outputPreferences = new VectorWritable(new RandomAccessSparseVector(Integer.MAX_VALUE, 2));
    outputPreferences.get().setQuick(5, 1.0);
    outputPreferences.get().setQuick(6, -1.0);

    context = mock(Reducer.Context.class);
  }
 public static VectorWritable merge(Iterator<VectorWritable> vectors) {
   Vector accumulator = vectors.next().get();
   while (vectors.hasNext()) {
     VectorWritable v = vectors.next();
     if (v != null) {
       Iterator<Vector.Element> nonZeroElements = v.get().iterateNonZero();
       while (nonZeroElements.hasNext()) {
         Vector.Element nonZeroElement = nonZeroElements.next();
         accumulator.setQuick(nonZeroElement.index(), nonZeroElement.get());
       }
     }
   }
   return new VectorWritable(accumulator);
 }