Untitled

 avatar
unknown
plain_text
a year ago
1.6 kB
4
Indexable
public static Query<Integer, Integer> pack() {
		return new Query<Integer, Integer>() {
			private List<Integer> buffer = new ArrayList<>();
			private int maxBits = 0;

			@Override
			public void start(Sink<Integer> sink) {
				buffer.clear();
				maxBits = 0;
			}

			@Override
			public void next(Integer item, Sink<Integer> sink) {
				buffer.add(item);
				int bitsNeeded = Integer.SIZE - Integer.numberOfLeadingZeros(item | 1);
				maxBits = Math.max(maxBits, bitsNeeded);
				if (buffer.size() % BLOCK_SIZE == 0) {
					flush(sink);
				}
			}

			@Override
			public void end(Sink<Integer> sink) {
				if (!buffer.isEmpty()) {
					flush(sink);
				}
				sink.end();
			}

			private void flush(Sink<Integer> sink) {
				sink.next(maxBits); // Assume maxBits fits in a single byte

				int currentByte = 0, bitsFilled = 0;
				for (Integer value : buffer) {
					int valueBits = maxBits;
					int bitsRemaining = valueBits;
					while (bitsRemaining > 0) {
						if (bitsFilled + bitsRemaining < 8) {
							currentByte |= (value << bitsFilled);
							bitsFilled += bitsRemaining;
							break;
						} else {
							int spaceLeft = 8 - bitsFilled;
							currentByte |= (value & ((1 << spaceLeft) - 1)) << bitsFilled;
							sink.next(currentByte);
							value >>>= spaceLeft;
							bitsRemaining -= spaceLeft;
							currentByte = 0;
							bitsFilled = 0;
						}
					}
				}
				if (bitsFilled > 0) {
					sink.next(currentByte);  // Send the last byte if it's not empty
				}
				buffer.clear();
				maxBits = 0;
			}
		};
	}
Editor is loading...
Leave a Comment