szetszwo commented on code in PR #9061:
URL: https://github.com/apache/ozone/pull/9061#discussion_r2386432154
##########
hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/spi/impl/KeyPrefixContainerCodec.java:
##########
@@ -50,26 +56,105 @@ public Class<KeyPrefixContainer> getTypeClass() {
return KeyPrefixContainer.class;
}
+ @Override
+ public boolean supportCodecBuffer() {
+ return true;
+ }
+
+ @Override
+ public CodecBuffer toCodecBuffer(@Nonnull KeyPrefixContainer object,
CodecBuffer.Allocator allocator) {
+ Preconditions.checkNotNull(object, "Null object can't be converted to
CodecBuffer.");
+
+ final byte[] keyPrefixBytes = object.getKeyPrefix().getBytes(UTF_8);
+ int totalSize = keyPrefixBytes.length;
+
+ if (object.getKeyVersion() != -1) {
+ totalSize += LONG_SERIALIZED_SIZE;
+ }
+ if (object.getContainerId() != -1) {
+ totalSize += LONG_SERIALIZED_SIZE;
+ }
+
+ final CodecBuffer buffer = allocator.apply(totalSize);
+ buffer.put(ByteBuffer.wrap(keyPrefixBytes));
+
+ if (object.getKeyVersion() != -1) {
+ buffer.put(KEY_DELIMITER_BUFFER.duplicate());
+ buffer.putLong(object.getKeyVersion());
+ }
+
+ if (object.getContainerId() != -1) {
+ buffer.put(KEY_DELIMITER_BUFFER.duplicate());
+ buffer.putLong(object.getContainerId());
+ }
+
+ return buffer;
+ }
+
+ @Override
+ public KeyPrefixContainer fromCodecBuffer(@Nonnull CodecBuffer buffer)
throws CodecException {
+ final ByteBuffer byteBuffer = buffer.asReadOnlyByteBuffer();
+ final int totalLength = byteBuffer.remaining();
+
+ if (totalLength == 0) {
+ throw new CodecException("Empty buffer");
+ }
+
+ final byte[] data = new byte[totalLength];
+ byteBuffer.get(data);
+
+ int lastDelimiter = findLastDelimiter(data);
+ if (lastDelimiter == -1) {
+ return KeyPrefixContainer.get(new String(data, UTF_8));
+ }
+
+ int secondLastDelimiter = findLastDelimiter(data, lastDelimiter - 1);
+ if (secondLastDelimiter == -1) {
+ String keyPrefix = new String(data, 0, lastDelimiter, UTF_8);
+ long version = Longs.fromByteArray(ArrayUtils.subarray(data,
+ lastDelimiter + 1, lastDelimiter + 1 + Long.BYTES));
+ return KeyPrefixContainer.get(keyPrefix, version);
+ }
+
+ String keyPrefix = new String(data, 0, secondLastDelimiter, UTF_8);
+ long version = Longs.fromByteArray(ArrayUtils.subarray(data,
+ secondLastDelimiter + 1, secondLastDelimiter + 1 + Long.BYTES));
+ long containerId = Longs.fromByteArray(ArrayUtils.subarray(data,
+ lastDelimiter + 1, lastDelimiter + 1 + Long.BYTES));
+
+ return KeyPrefixContainer.get(keyPrefix, version, containerId);
+ }
+
+ private int findLastDelimiter(byte[] data) {
+ return findLastDelimiter(data, data.length - 1);
+ }
+
+ private int findLastDelimiter(byte[] data, int endPos) {
+ for (int i = endPos - Long.BYTES; i >= 0; i--) {
+ if (data[i] == '_') {
+ return i;
+ }
+ }
+ return -1;
+ }
+
@Override
public byte[] toPersistedFormat(KeyPrefixContainer keyPrefixContainer) {
Preconditions.checkNotNull(keyPrefixContainer,
"Null object can't be converted to byte array.");
byte[] keyPrefixBytes = keyPrefixContainer.getKeyPrefix().getBytes(UTF_8);
- //Prefix seek can be done only with keyPrefix. In that case, we can
+ // Prefix seek can be done only with keyPrefix. In that case, we can
// expect the version and the containerId to be undefined.
if (keyPrefixContainer.getKeyVersion() != -1) {
- keyPrefixBytes = ArrayUtils.addAll(keyPrefixBytes, KEY_DELIMITER
- .getBytes(UTF_8));
+ keyPrefixBytes = ArrayUtils.addAll(keyPrefixBytes, KEY_DELIMITER_BYTES);
keyPrefixBytes = ArrayUtils.addAll(keyPrefixBytes, Longs.toByteArray(
keyPrefixContainer.getKeyVersion()));
- }
-
- if (keyPrefixContainer.getContainerId() != -1) {
- keyPrefixBytes = ArrayUtils.addAll(keyPrefixBytes, KEY_DELIMITER
- .getBytes(UTF_8));
- keyPrefixBytes = ArrayUtils.addAll(keyPrefixBytes, Longs.toByteArray(
- keyPrefixContainer.getContainerId()));
+ if (keyPrefixContainer.getContainerId() != -1) {
+ keyPrefixBytes = ArrayUtils.addAll(keyPrefixBytes,
KEY_DELIMITER_BYTES);
+ keyPrefixBytes = ArrayUtils.addAll(keyPrefixBytes, Longs.toByteArray(
+ keyPrefixContainer.getContainerId()));
+ }
Review Comment:
It is good to fix the bug.
`toCodecBuffer` should use a similar logic.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]