Write monotonically-increasing sequences of integers. This writer splits data into blocks and then for each block, computes the average slope, the minimum value and only encode the delta from the expected value using a DirectWriter.
/** * Write a new value. Note that data might not make it to storage until * {@link #finish()} is called. * * @throws IllegalArgumentException if values don't come in order * 写一个新的值, * 但是不一定立即存储,可能在finish的时候才存储 * 如果传入的值不是递增的,就报错 */ publicvoidadd(long v)throws IOException { // 检查是否是单调递增 if (v < previous) { thrownewIllegalArgumentException("Values do not come in order: " + previous + ", " + v); } // 内部缓冲区满,意味着,分块的一块满了, 缓冲区是之前根据分块大小算好的 if (bufferSize == buffer.length) { flush(); }
// 但是存的不是真实值,而是偏移量 longmin= buffer[0]; for (inti=1; i < bufferSize; ++i) { min = Math.min(buffer[i], min); }
// 每个位置上存储的,不是偏移量了,而是偏移量与最小的值的偏移量 // 然后算个最大偏移量 longmaxDelta=0; for (inti=0; i < bufferSize; ++i) { buffer[i] -= min; // use | will change nothing when it comes to computing required bits // but has the benefit of working fine with negative values too // (in case of overflow) maxDelta |= buffer[i]; }
/** * This must be called exactly once after all values have been {@link #add(long) added}. * 所有数字都被调用过all之后, * 要调用且只能调用一次finish. */ publicvoidfinish()throws IOException { if (count != numValues) { thrownewIllegalStateException("Wrong number of values added, expected: " + numValues + ", got: " + count); } // 保证只能调用一次 if (finished) { thrownewIllegalStateException("#finish has been called already"); } // 调用finish的时候,有缓冲就直接写,反正也只能调用一次 if (bufferSize > 0) { flush(); } finished = true; }