This is an automated email from the ASF dual-hosted git repository.
szetszwo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git
The following commit(s) were added to refs/heads/master by this push:
new 8e32bc46964 HDDS-14957. Separate OpenKeyInfo to differentiate KeyInfo
(#10181)
8e32bc46964 is described below
commit 8e32bc46964000d42768f1e99b7dbf8036b202b9
Author: Bolin Lin <[email protected]>
AuthorDate: Tue Jul 14 02:28:50 2026 -0400
HDDS-14957. Separate OpenKeyInfo to differentiate KeyInfo (#10181)
---
.../apache/hadoop/ozone/om/helpers/OmKeyInfo.java | 71 +++++++++--
.../hadoop/ozone/om/helpers/RepeatedOmKeyInfo.java | 44 ++++++-
.../ozone/om/helpers/TestOmKeyInfoCodec.java | 132 ++++++++++++++++++++-
.../om/helpers/TestRepeatedOmKeyInfoCodec.java | 109 ++++++++++++++++-
.../hadoop/ozone/om/codec/OMDBDefinition.java | 23 ++--
.../ozone/om/request/key/OMKeyCommitRequest.java | 3 -
.../om/request/key/OMKeyCommitRequestWithFSO.java | 4 +-
.../om/request/key/TestOMKeyCommitRequest.java | 2 -
8 files changed, 347 insertions(+), 41 deletions(-)
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmKeyInfo.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmKeyInfo.java
index 4d8d3d4c7eb..ab4da4badd9 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmKeyInfo.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/OmKeyInfo.java
@@ -60,7 +60,8 @@ public final class OmKeyInfo extends WithParentObjectId
implements CopyObject<OmKeyInfo>, WithTags {
private static final Logger LOG = LoggerFactory.getLogger(OmKeyInfo.class);
- private static final Codec<OmKeyInfo> CODEC = newCodec();
+ private static final Codec<OmKeyInfo> CODEC = newCodec(true);
+ private static final Codec<OmKeyInfo> CODEC_KEY_TABLE = newCodec(false);
/**
* Metadata key flag to indicate whether a deleted key was a committed key.
* The flag is set when a committed key is deleted from AOS but still held in
@@ -109,7 +110,7 @@ public final class OmKeyInfo extends WithParentObjectId
// generation unchanged.
// This allows a key to be created an committed atomically if the original
has not
// been modified.
- private Long expectedDataGeneration = null;
+ private final Long expectedDataGeneration;
private OmKeyInfo(Builder b) {
super(b);
@@ -131,18 +132,41 @@ private OmKeyInfo(Builder b) {
this.expectedDataGeneration = b.expectedDataGeneration;
}
- private static Codec<OmKeyInfo> newCodec() {
+ /**
+ * Creates a new codec for OmKeyInfo.
+ *
+ * @param isOpenKey true for openKeyTable (includes expectedDataGeneration),
+ * false for keyTable (excludes these fields)
+ * @return the codec
+ */
+ private static Codec<OmKeyInfo> newCodec(boolean isOpenKey) {
return new DelegatedCodec<>(
Proto2Codec.get(KeyInfo.getDefaultInstance()),
OmKeyInfo::getFromProtobuf,
- k -> k.getProtobuf(true, ClientVersion.CURRENT_VERSION),
+ k -> k.getProtobuf(true, ClientVersion.CURRENT_VERSION, isOpenKey),
OmKeyInfo.class);
}
- public static Codec<OmKeyInfo> getCodec() {
+ /**
+ * Gets the codec for openKeyTable. This codec includes
expectedDataGeneration
+ * field during serialization.
+ *
+ * @return the codec for openKeyTable
+ */
+ public static Codec<OmKeyInfo> getOpenKeyTableCodec() {
return CODEC;
}
+ /**
+ * Gets the codec for keyTable. This codec excludes fields that are only
+ * meaningful for open keys.
+ *
+ * @return the codec for keyTable
+ */
+ public static Codec<OmKeyInfo> getKeyTableCodec() {
+ return CODEC_KEY_TABLE;
+ }
+
public String getVolumeName() {
return volumeName;
}
@@ -180,10 +204,6 @@ public String getFileName() {
return fileName;
}
- public void setExpectedDataGeneration(Long generation) {
- this.expectedDataGeneration = generation;
- }
-
public Long getExpectedDataGeneration() {
return expectedDataGeneration;
}
@@ -737,7 +757,20 @@ public KeyInfo getNetworkProtobuf(String fullKeyName, int
clientVersion,
* @return KeyInfo
*/
public KeyInfo getProtobuf(boolean ignorePipeline, int clientVersion) {
- return getProtobuf(ignorePipeline, null, clientVersion, false);
+ return getProtobuf(ignorePipeline, null, clientVersion, false, true);
+ }
+
+ /**
+ * Gets KeyInfo for persistence with control over fields only used in
openKeyTable.
+ *
+ * @param ignorePipeline true for persist to DB, false for network transmit.
+ * @param clientVersion the client version
+ * @param isOpenKey true for openKeyTable, false for keyTable
+ * @return KeyInfo
+ */
+ public KeyInfo getProtobuf(boolean ignorePipeline, int clientVersion,
+ boolean isOpenKey) {
+ return getProtobuf(ignorePipeline, null, clientVersion, false, isOpenKey);
}
/**
@@ -749,6 +782,22 @@ public KeyInfo getProtobuf(boolean ignorePipeline, int
clientVersion) {
*/
private KeyInfo getProtobuf(boolean ignorePipeline, String fullKeyName,
int clientVersion, boolean latestVersionBlocks) {
+ return getProtobuf(ignorePipeline, fullKeyName, clientVersion,
latestVersionBlocks, true);
+ }
+
+ /**
+ * Gets KeyInfo with all parameters.
+ *
+ * @param ignorePipeline ignore pipeline flag
+ * @param fullKeyName user given key name
+ * @param clientVersion the client version
+ * @param latestVersionBlocks whether to include only latest version blocks
+ * @param isOpenKey true for openKeyTable, false for keyTable
+ * @return key info object
+ */
+ private KeyInfo getProtobuf(boolean ignorePipeline, String fullKeyName,
+ int clientVersion, boolean latestVersionBlocks,
+ boolean isOpenKey) {
long latestVersion = keyLocationVersions.isEmpty() ? -1 :
keyLocationVersions.get(keyLocationVersions.size() - 1).getVersion();
@@ -800,7 +849,7 @@ private KeyInfo getProtobuf(boolean ignorePipeline, String
fullKeyName,
kb.setFileEncryptionInfo(OMPBHelper.convert(encInfo));
}
kb.setIsFile(isFile);
- if (expectedDataGeneration != null) {
+ if (isOpenKey && expectedDataGeneration != null) {
kb.setExpectedDataGeneration(expectedDataGeneration);
}
if (ownerName != null) {
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/RepeatedOmKeyInfo.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/RepeatedOmKeyInfo.java
index 0f10832114e..cf37681a793 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/RepeatedOmKeyInfo.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/RepeatedOmKeyInfo.java
@@ -37,8 +37,13 @@
* admin wants to confirm if a given key is deleted from deletedTable metadata.
*/
public class RepeatedOmKeyInfo implements CopyObject<RepeatedOmKeyInfo> {
- private static final Codec<RepeatedOmKeyInfo> CODEC_TRUE = newCodec(true);
- private static final Codec<RepeatedOmKeyInfo> CODEC_FALSE = newCodec(false);
+
+ private static final Codec<RepeatedOmKeyInfo> CODEC_TRUE = newCodec(true,
true);
+ private static final Codec<RepeatedOmKeyInfo> CODEC_FALSE = newCodec(false,
true);
+
+ // Codecs for deletedTable - exclude fields only used in openKeyTable
+ private static final Codec<RepeatedOmKeyInfo> CODEC_DELETED_TABLE_TRUE =
newCodec(true, false);
+ private static final Codec<RepeatedOmKeyInfo> CODEC_DELETED_TABLE_FALSE =
newCodec(false, false);
private final List<OmKeyInfo> omKeyInfoList;
/**
@@ -51,18 +56,36 @@ public class RepeatedOmKeyInfo implements
CopyObject<RepeatedOmKeyInfo> {
*/
private final long bucketId;
- private static Codec<RepeatedOmKeyInfo> newCodec(boolean ignorePipeline) {
+ private static Codec<RepeatedOmKeyInfo> newCodec(boolean ignorePipeline,
boolean isOpenKey) {
return new DelegatedCodec<>(
Proto2Codec.get(RepeatedKeyInfo.getDefaultInstance()),
RepeatedOmKeyInfo::getFromProto,
- k -> k.getProto(ignorePipeline, ClientVersion.CURRENT_VERSION),
+ k -> k.getProto(ignorePipeline, ClientVersion.CURRENT_VERSION,
isOpenKey),
RepeatedOmKeyInfo.class);
}
- public static Codec<RepeatedOmKeyInfo> getCodec(boolean ignorePipeline) {
+ /**
+ * Gets the codec for openKeyTable. This codec includes fields only used in
+ * openKeyTable during serialization.
+ *
+ * @param ignorePipeline whether to ignore pipeline info
+ * @return the codec for openKeyTable
+ */
+ public static Codec<RepeatedOmKeyInfo> getOpenKeyTableCodec(boolean
ignorePipeline) {
return ignorePipeline ? CODEC_TRUE : CODEC_FALSE;
}
+ /**
+ * Gets the codec for deletedTable. This codec excludes fields only used in
+ * openKeyTable during serialization, as deleted keys are committed keys.
+ *
+ * @param ignorePipeline whether to ignore pipeline info
+ * @return the codec for deletedTable
+ */
+ public static Codec<RepeatedOmKeyInfo> getDeletedTableCodec(boolean
ignorePipeline) {
+ return ignorePipeline ? CODEC_DELETED_TABLE_TRUE :
CODEC_DELETED_TABLE_FALSE;
+ }
+
public RepeatedOmKeyInfo(long bucketId) {
this.omKeyInfoList = new ArrayList<>();
this.bucketId = bucketId;
@@ -129,9 +152,18 @@ public static RepeatedOmKeyInfo
getFromProto(RepeatedKeyInfo repeatedKeyInfo) {
* @param compact true for persistence, false for network transmit
*/
public RepeatedKeyInfo getProto(boolean compact, int clientVersion) {
+ return getProto(compact, clientVersion, true);
+ }
+
+ /**
+ * @param compact true for persistence, false for network transmit
+ * @param clientVersion the client version
+ * @param isOpenKey true for openKeyTable, false for keyTable/deletedTable
+ */
+ public RepeatedKeyInfo getProto(boolean compact, int clientVersion, boolean
isOpenKey) {
List<KeyInfo> list = new ArrayList<>();
for (OmKeyInfo k : cloneOmKeyInfoList()) {
- list.add(k.getProtobuf(compact, clientVersion));
+ list.add(k.getProtobuf(compact, clientVersion, isOpenKey));
}
RepeatedKeyInfo.Builder builder = RepeatedKeyInfo.newBuilder()
diff --git
a/hadoop-ozone/interface-storage/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmKeyInfoCodec.java
b/hadoop-ozone/interface-storage/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmKeyInfoCodec.java
index bc568eea837..3de8f4677d8 100644
---
a/hadoop-ozone/interface-storage/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmKeyInfoCodec.java
+++
b/hadoop-ozone/interface-storage/src/test/java/org/apache/hadoop/ozone/om/helpers/TestOmKeyInfoCodec.java
@@ -18,8 +18,10 @@
package org.apache.hadoop.ozone.om.helpers;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.util.ArrayList;
@@ -35,6 +37,7 @@
import org.apache.hadoop.hdds.utils.db.Codec;
import org.apache.hadoop.hdds.utils.db.Proto2CodecTestBase;
import org.apache.hadoop.io.MD5Hash;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.KeyInfo;
import org.apache.hadoop.util.Time;
import org.junit.jupiter.api.Test;
@@ -51,7 +54,7 @@ public class TestOmKeyInfoCodec extends
Proto2CodecTestBase<OmKeyInfo> {
@Override
public Codec<OmKeyInfo> getCodec() {
- return OmKeyInfo.getCodec();
+ return OmKeyInfo.getOpenKeyTableCodec();
}
private static FileChecksum createEmptyChecksum() {
@@ -92,6 +95,42 @@ private OmKeyInfo getKeyInfo(int chunkNum) {
.build();
}
+ /**
+ * Creates an OmKeyInfo with fields only used in openKeyTable set.
+ * The expectedDataGeneration field is only meaningful for keys in
openKeyTable.
+ */
+ private OmKeyInfo getKeyInfoWithOpenKeyFields(int chunkNum) {
+ List<OmKeyLocationInfo> omKeyLocationInfoList = new ArrayList<>();
+ Pipeline pipeline = HddsTestUtils.getRandomPipeline();
+ for (int i = 0; i < chunkNum; i++) {
+ BlockID blockID = new BlockID(i, i);
+ OmKeyLocationInfo keyLocationInfo = new OmKeyLocationInfo.Builder()
+ .setBlockID(blockID)
+ .setPipeline(pipeline)
+ .build();
+ omKeyLocationInfoList.add(keyLocationInfo);
+ }
+ OmKeyLocationInfoGroup omKeyLocationInfoGroup = new
+ OmKeyLocationInfoGroup(0, omKeyLocationInfoList);
+
+ return new OmKeyInfo.Builder()
+ .setCreationTime(Time.now())
+ .setModificationTime(Time.now())
+ .setReplicationConfig(RatisReplicationConfig
+ .getInstance(HddsProtos.ReplicationFactor.THREE))
+ .setVolumeName(VOLUME)
+ .setBucketName(BUCKET)
+ .setKeyName(KEYNAME)
+ .setObjectID(Time.now())
+ .setUpdateID(Time.now())
+ .setDataSize(100)
+ .setOmKeyLocationInfos(
+ Collections.singletonList(omKeyLocationInfoGroup))
+ .setFileChecksum(checksum)
+ .setExpectedDataGeneration(12345L)
+ .build();
+ }
+
@Test
public void test() throws IOException {
testOmKeyInfoCodecWithoutPipeline(1);
@@ -100,7 +139,7 @@ public void test() throws IOException {
public void testOmKeyInfoCodecWithoutPipeline(int chunkNum)
throws IOException {
- final Codec<OmKeyInfo> codec = OmKeyInfo.getCodec();
+ final Codec<OmKeyInfo> codec = OmKeyInfo.getOpenKeyTableCodec();
OmKeyInfo originKey = getKeyInfo(chunkNum);
byte[] rawData = codec.toPersistedFormat(originKey);
OmKeyInfo key = codec.fromPersistedFormat(rawData);
@@ -111,4 +150,93 @@ public void testOmKeyInfoCodecWithoutPipeline(int chunkNum)
assertNotNull(key.getFileChecksum());
assertEquals(key.getFileChecksum(), checksum);
}
+
+ @Test
+ public void testOpenKeyTableCodecIncludesOpenKeyFields() throws IOException {
+ final Codec<OmKeyInfo> openKeyCodec = OmKeyInfo.getOpenKeyTableCodec();
+ OmKeyInfo originKey = getKeyInfoWithOpenKeyFields(1);
+
+ assertEquals(12345L, originKey.getExpectedDataGeneration());
+
+ byte[] rawData = openKeyCodec.toPersistedFormat(originKey);
+ OmKeyInfo deserializedKey = openKeyCodec.fromPersistedFormat(rawData);
+
+ assertEquals(12345L, deserializedKey.getExpectedDataGeneration());
+
+ KeyInfo keyInfo = KeyInfo.parseFrom(rawData);
+ assertTrue(keyInfo.hasExpectedDataGeneration(),
+ "openKeyTable codec should include expectedDataGeneration in proto");
+ assertEquals(12345L, keyInfo.getExpectedDataGeneration());
+ }
+
+ @Test
+ public void testKeyTableCodecExcludesOpenKeyFields() throws IOException {
+ final Codec<OmKeyInfo> keyTableCodec = OmKeyInfo.getKeyTableCodec();
+ OmKeyInfo originKey = getKeyInfoWithOpenKeyFields(1);
+ assertEquals(12345L, originKey.getExpectedDataGeneration());
+
+ byte[] rawData = keyTableCodec.toPersistedFormat(originKey);
+ KeyInfo keyInfo = KeyInfo.parseFrom(rawData);
+ assertFalse(keyInfo.hasExpectedDataGeneration(),
+ "keyTable codec should NOT include expectedDataGeneration in proto");
+
+ OmKeyInfo deserializedKey = keyTableCodec.fromPersistedFormat(rawData);
+ assertEquals(VOLUME, deserializedKey.getVolumeName());
+ assertEquals(BUCKET, deserializedKey.getBucketName());
+ assertEquals(KEYNAME, deserializedKey.getKeyName());
+ assertEquals(100, deserializedKey.getDataSize());
+
+ assertNull(deserializedKey.getExpectedDataGeneration(),
+ "Deserialized key from keyTable should have null
expectedDataGeneration");
+ }
+
+ @Test
+ public void testKeyTableCodecCanReadOpenKeyTableData() throws IOException {
+ final Codec<OmKeyInfo> openKeyCodec = OmKeyInfo.getOpenKeyTableCodec();
+ final Codec<OmKeyInfo> keyTableCodec = OmKeyInfo.getKeyTableCodec();
+
+ OmKeyInfo originKey = getKeyInfoWithOpenKeyFields(1);
+ byte[] rawData = openKeyCodec.toPersistedFormat(originKey);
+ OmKeyInfo deserializedKey = keyTableCodec.fromPersistedFormat(rawData);
+
+ assertEquals(VOLUME, deserializedKey.getVolumeName());
+ assertEquals(BUCKET, deserializedKey.getBucketName());
+ assertEquals(12345L, deserializedKey.getExpectedDataGeneration());
+ }
+
+ @Test
+ public void testCodecsWithKeyWithoutOpenKeyFields() throws IOException {
+ final Codec<OmKeyInfo> openKeyCodec = OmKeyInfo.getOpenKeyTableCodec();
+ final Codec<OmKeyInfo> keyTableCodec = OmKeyInfo.getKeyTableCodec();
+
+ OmKeyInfo originKey = getKeyInfo(1);
+ assertNull(originKey.getExpectedDataGeneration());
+
+ byte[] openKeyData = openKeyCodec.toPersistedFormat(originKey);
+ byte[] keyTableData = keyTableCodec.toPersistedFormat(originKey);
+
+ OmKeyInfo fromOpenKeyCodec = openKeyCodec.fromPersistedFormat(openKeyData);
+ OmKeyInfo fromKeyTableCodec =
keyTableCodec.fromPersistedFormat(keyTableData);
+
+ assertEquals(VOLUME, fromOpenKeyCodec.getVolumeName());
+ assertEquals(VOLUME, fromKeyTableCodec.getVolumeName());
+ assertEquals(BUCKET, fromOpenKeyCodec.getBucketName());
+ assertEquals(BUCKET, fromKeyTableCodec.getBucketName());
+ assertNull(fromOpenKeyCodec.getExpectedDataGeneration());
+ assertNull(fromKeyTableCodec.getExpectedDataGeneration());
+ }
+
+ @Test
+ public void testKeyTableCodecProducesSmallerOutput() throws IOException {
+ final Codec<OmKeyInfo> openKeyCodec = OmKeyInfo.getOpenKeyTableCodec();
+ final Codec<OmKeyInfo> keyTableCodec = OmKeyInfo.getKeyTableCodec();
+
+ OmKeyInfo keyWithOpenFields = getKeyInfoWithOpenKeyFields(1);
+
+ byte[] openKeyData = openKeyCodec.toPersistedFormat(keyWithOpenFields);
+ byte[] keyTableData = keyTableCodec.toPersistedFormat(keyWithOpenFields);
+
+ assertTrue(keyTableData.length < openKeyData.length,
+ "keyTable codec should produce smaller serialized output when
openKeyTable-only fields are set");
+ }
}
diff --git
a/hadoop-ozone/interface-storage/src/test/java/org/apache/hadoop/ozone/om/helpers/TestRepeatedOmKeyInfoCodec.java
b/hadoop-ozone/interface-storage/src/test/java/org/apache/hadoop/ozone/om/helpers/TestRepeatedOmKeyInfoCodec.java
index 3227cfbe6a4..fdd7c64a730 100644
---
a/hadoop-ozone/interface-storage/src/test/java/org/apache/hadoop/ozone/om/helpers/TestRepeatedOmKeyInfoCodec.java
+++
b/hadoop-ozone/interface-storage/src/test/java/org/apache/hadoop/ozone/om/helpers/TestRepeatedOmKeyInfoCodec.java
@@ -21,6 +21,7 @@
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.io.IOException;
@@ -36,11 +37,12 @@
import org.apache.hadoop.hdds.scm.pipeline.Pipeline;
import org.apache.hadoop.hdds.utils.db.Codec;
import org.apache.hadoop.hdds.utils.db.Proto2CodecTestBase;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.RepeatedKeyInfo;
import org.apache.hadoop.util.Time;
import org.junit.jupiter.api.Test;
/**
- * Test {@link RepeatedOmKeyInfo#getCodec(boolean)}.
+ * Test {@link RepeatedOmKeyInfo#getOpenKeyTableCodec(boolean)}.
*/
public class TestRepeatedOmKeyInfoCodec
extends Proto2CodecTestBase<RepeatedOmKeyInfo> {
@@ -51,7 +53,7 @@ public class TestRepeatedOmKeyInfoCodec
@Override
public Codec<RepeatedOmKeyInfo> getCodec() {
- return RepeatedOmKeyInfo.getCodec(true);
+ return RepeatedOmKeyInfo.getOpenKeyTableCodec(true);
}
private OmKeyInfo getKeyInfo(int chunkNum) {
@@ -94,7 +96,7 @@ void test() throws Exception {
}
public void testWithoutPipeline(int chunkNum) throws IOException {
- final Codec<RepeatedOmKeyInfo> codec = RepeatedOmKeyInfo.getCodec(true);
+ final Codec<RepeatedOmKeyInfo> codec =
RepeatedOmKeyInfo.getOpenKeyTableCodec(true);
OmKeyInfo originKey = getKeyInfo(chunkNum);
long bucketId = Time.now();
RepeatedOmKeyInfo repeatedOmKeyInfo = new RepeatedOmKeyInfo(originKey,
bucketId);
@@ -108,9 +110,9 @@ public void testWithoutPipeline(int chunkNum) throws
IOException {
public void testCompatibility(int chunkNum) throws IOException {
final Codec<RepeatedOmKeyInfo> codecWithoutPipeline
- = RepeatedOmKeyInfo.getCodec(true);
+ = RepeatedOmKeyInfo.getOpenKeyTableCodec(true);
final Codec<RepeatedOmKeyInfo> codecWithPipeline
- = RepeatedOmKeyInfo.getCodec(false);
+ = RepeatedOmKeyInfo.getOpenKeyTableCodec(false);
OmKeyInfo originKey = getKeyInfo(chunkNum);
long bucketId = Time.now();
RepeatedOmKeyInfo repeatedOmKeyInfo = new RepeatedOmKeyInfo(originKey,
bucketId);
@@ -125,7 +127,7 @@ public void threadSafety() throws InterruptedException {
final OmKeyInfo key = getKeyInfo(1);
long bucketId = Time.now();
final RepeatedOmKeyInfo subject = new RepeatedOmKeyInfo(key, bucketId);
- final Codec<RepeatedOmKeyInfo> codec = RepeatedOmKeyInfo.getCodec(true);
+ final Codec<RepeatedOmKeyInfo> codec =
RepeatedOmKeyInfo.getOpenKeyTableCodec(true);
final AtomicBoolean failed = new AtomicBoolean();
ThreadFactory threadFactory = new ThreadFactoryBuilder().setDaemon(true)
.build();
@@ -150,4 +152,99 @@ public void threadSafety() throws InterruptedException {
}
assertFalse(failed.get());
}
+
+ private OmKeyInfo getKeyInfoWithOpenKeyFields(int chunkNum) {
+ List<OmKeyLocationInfo> omKeyLocationInfoList = new ArrayList<>();
+ Pipeline pipeline = HddsTestUtils.getRandomPipeline();
+ for (int i = 0; i < chunkNum; i++) {
+ BlockID blockID = new BlockID(i, i);
+ OmKeyLocationInfo keyLocationInfo = new OmKeyLocationInfo.Builder()
+ .setBlockID(blockID)
+ .setPipeline(pipeline)
+ .build();
+ omKeyLocationInfoList.add(keyLocationInfo);
+ }
+ OmKeyLocationInfoGroup omKeyLocationInfoGroup = new
+ OmKeyLocationInfoGroup(0, omKeyLocationInfoList);
+ return new OmKeyInfo.Builder()
+ .setCreationTime(Time.now())
+ .setModificationTime(Time.now())
+ .setReplicationConfig(
+ RatisReplicationConfig
+ .getInstance(HddsProtos.ReplicationFactor.THREE))
+ .setVolumeName(VOLUME)
+ .setBucketName(BUCKET)
+ .setKeyName(KEYNAME)
+ .setObjectID(Time.now())
+ .setUpdateID(Time.now())
+ .setDataSize(100)
+ .setOmKeyLocationInfos(
+ Collections.singletonList(omKeyLocationInfoGroup))
+ .setExpectedDataGeneration(12345L)
+ .build();
+ }
+
+ @Test
+ void testRegularCodecIncludesOpenKeyFields() throws IOException {
+ final Codec<RepeatedOmKeyInfo> codec =
RepeatedOmKeyInfo.getOpenKeyTableCodec(true);
+ OmKeyInfo keyWithFields = getKeyInfoWithOpenKeyFields(1);
+ long bucketId = Time.now();
+ RepeatedOmKeyInfo repeatedOmKeyInfo = new RepeatedOmKeyInfo(keyWithFields,
bucketId);
+
+ byte[] rawData = codec.toPersistedFormat(repeatedOmKeyInfo);
+ RepeatedKeyInfo proto = RepeatedKeyInfo.parseFrom(rawData);
+
+ assertTrue(proto.getKeyInfo(0).hasExpectedDataGeneration());
+ assertEquals(12345L, proto.getKeyInfo(0).getExpectedDataGeneration());
+ }
+
+ @Test
+ void testDeletedTableCodecExcludesOpenKeyFields() throws IOException {
+ final Codec<RepeatedOmKeyInfo> codec =
RepeatedOmKeyInfo.getDeletedTableCodec(true);
+ OmKeyInfo keyWithFields = getKeyInfoWithOpenKeyFields(1);
+ long bucketId = Time.now();
+ RepeatedOmKeyInfo repeatedOmKeyInfo = new RepeatedOmKeyInfo(keyWithFields,
bucketId);
+
+ byte[] rawData = codec.toPersistedFormat(repeatedOmKeyInfo);
+ RepeatedKeyInfo proto = RepeatedKeyInfo.parseFrom(rawData);
+
+ assertFalse(proto.getKeyInfo(0).hasExpectedDataGeneration());
+
+ RepeatedOmKeyInfo deserialized = codec.fromPersistedFormat(rawData);
+ assertEquals(VOLUME,
deserialized.getOmKeyInfoList().get(0).getVolumeName());
+ assertEquals(BUCKET,
deserialized.getOmKeyInfoList().get(0).getBucketName());
+ assertEquals(bucketId, deserialized.getBucketId());
+ }
+
+ @Test
+ void testDeletedTableCodecCanReadRegularCodecData() throws IOException {
+ final Codec<RepeatedOmKeyInfo> regularCodec =
RepeatedOmKeyInfo.getOpenKeyTableCodec(true);
+ final Codec<RepeatedOmKeyInfo> deletedTableCodec =
RepeatedOmKeyInfo.getDeletedTableCodec(true);
+
+ OmKeyInfo keyWithFields = getKeyInfoWithOpenKeyFields(1);
+ long bucketId = Time.now();
+ RepeatedOmKeyInfo repeatedOmKeyInfo = new RepeatedOmKeyInfo(keyWithFields,
bucketId);
+
+ byte[] rawData = regularCodec.toPersistedFormat(repeatedOmKeyInfo);
+ RepeatedOmKeyInfo deserialized =
deletedTableCodec.fromPersistedFormat(rawData);
+
+ assertEquals(VOLUME,
deserialized.getOmKeyInfoList().get(0).getVolumeName());
+ assertEquals(12345L,
deserialized.getOmKeyInfoList().get(0).getExpectedDataGeneration());
+ }
+
+ @Test
+ void testDeletedTableCodecProducesSmallerOutput() throws IOException {
+ final Codec<RepeatedOmKeyInfo> regularCodec =
RepeatedOmKeyInfo.getOpenKeyTableCodec(true);
+ final Codec<RepeatedOmKeyInfo> deletedTableCodec =
RepeatedOmKeyInfo.getDeletedTableCodec(true);
+
+ OmKeyInfo keyWithFields = getKeyInfoWithOpenKeyFields(1);
+ long bucketId = Time.now();
+ RepeatedOmKeyInfo repeatedOmKeyInfo = new RepeatedOmKeyInfo(keyWithFields,
bucketId);
+
+ byte[] regularData = regularCodec.toPersistedFormat(repeatedOmKeyInfo);
+ byte[] deletedTableData =
deletedTableCodec.toPersistedFormat(repeatedOmKeyInfo);
+
+ assertTrue(deletedTableData.length < regularData.length,
+ "deletedTable codec should produce smaller output");
+ }
}
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/codec/OMDBDefinition.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/codec/OMDBDefinition.java
index e41a7b15445..02e32edec46 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/codec/OMDBDefinition.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/codec/OMDBDefinition.java
@@ -204,25 +204,25 @@ public final class OMDBDefinition extends
DBDefinition.WithMap {
//---------------------------------------------------------------------------
// Object Store (OBS) Tables:
public static final String KEY_TABLE = "keyTable";
- /** keyTable: /volume/bucket/key :- KeyInfo. */
+ /** keyTable: /volume/bucket/key :- KeyInfo (excludes fields only used in
openKeyTable). */
public static final DBColumnFamilyDefinition<String, OmKeyInfo> KEY_TABLE_DEF
= new DBColumnFamilyDefinition<>(KEY_TABLE,
StringCodec.get(),
- OmKeyInfo.getCodec());
+ OmKeyInfo.getKeyTableCodec());
public static final String DELETED_TABLE = "deletedTable";
- /** deletedTable: /volume/bucket/key :- RepeatedKeyInfo. */
+ /** deletedTable: /volume/bucket/key :- RepeatedKeyInfo (excludes fields
only used in openKeyTable). */
public static final DBColumnFamilyDefinition<String, RepeatedOmKeyInfo>
DELETED_TABLE_DEF
= new DBColumnFamilyDefinition<>(DELETED_TABLE,
StringCodec.get(),
- RepeatedOmKeyInfo.getCodec(true));
+ RepeatedOmKeyInfo.getDeletedTableCodec(true));
public static final String OPEN_KEY_TABLE = "openKeyTable";
/** openKeyTable: /volume/bucket/key/id :- KeyInfo. */
public static final DBColumnFamilyDefinition<String, OmKeyInfo>
OPEN_KEY_TABLE_DEF
= new DBColumnFamilyDefinition<>(OPEN_KEY_TABLE,
StringCodec.get(),
- OmKeyInfo.getCodec());
+ OmKeyInfo.getOpenKeyTableCodec());
public static final String MULTIPART_INFO_TABLE = "multipartInfoTable";
/** multipartInfoTable: /volume/bucket/key/uploadId :- parts. */
@@ -241,18 +241,18 @@ public final class OMDBDefinition extends
DBDefinition.WithMap {
//---------------------------------------------------------------------------
// File System Optimized (FSO) Tables:
public static final String FILE_TABLE = "fileTable";
- /** fileTable: /volumeId/bucketId/parentId/fileName :- KeyInfo. */
+ /** fileTable: /volumeId/bucketId/parentId/fileName :- KeyInfo (excludes
fields only used in openKeyTable). */
public static final DBColumnFamilyDefinition<String, OmKeyInfo>
FILE_TABLE_DEF
= new DBColumnFamilyDefinition<>(FILE_TABLE,
StringCodec.get(),
- OmKeyInfo.getCodec());
+ OmKeyInfo.getKeyTableCodec());
public static final String OPEN_FILE_TABLE = "openFileTable";
/** openFileTable: /volumeId/bucketId/parentId/fileName/id :- KeyInfo. */
public static final DBColumnFamilyDefinition<String, OmKeyInfo>
OPEN_FILE_TABLE_DEF
= new DBColumnFamilyDefinition<>(OPEN_FILE_TABLE,
StringCodec.get(),
- OmKeyInfo.getCodec());
+ OmKeyInfo.getOpenKeyTableCodec());
public static final String DIRECTORY_TABLE = "directoryTable";
/** directoryTable: /volumeId/bucketId/parentId/dirName :- DirInfo. */
@@ -262,11 +262,14 @@ public final class OMDBDefinition extends
DBDefinition.WithMap {
OmDirectoryInfo.getCodec());
public static final String DELETED_DIR_TABLE = "deletedDirectoryTable";
- /** deletedDirectoryTable: /volumeId/bucketId/parentId/dirName/objectId :-
KeyInfo. */
+ /**
+ * deletedDirectoryTable: /volumeId/bucketId/parentId/dirName/objectId :-
KeyInfo
+ * (excludes fields only used in openKeyTable).
+ */
public static final DBColumnFamilyDefinition<String, OmKeyInfo>
DELETED_DIR_TABLE_DEF
= new DBColumnFamilyDefinition<>(DELETED_DIR_TABLE,
StringCodec.get(),
- OmKeyInfo.getCodec());
+ OmKeyInfo.getKeyTableCodec());
//---------------------------------------------------------------------------
// S3 Multi-Tenancy Tables
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeyCommitRequest.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeyCommitRequest.java
index 4e1d3603d73..6c34443058b 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeyCommitRequest.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeyCommitRequest.java
@@ -303,9 +303,6 @@ public OMClientResponse validateAndUpdateCache(OzoneManager
ozoneManager, Execut
}
validateAtomicRewrite(keyToDelete, omKeyInfo, auditMap);
- // Optimistic locking validation has passed. Now set the rewrite fields
to null so they are
- // not persisted in the key table.
- // Combination
// Set the UpdateID to current transactionLogIndex
omKeyInfo = omKeyInfo.toBuilder()
.setExpectedDataGeneration(null)
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeyCommitRequestWithFSO.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeyCommitRequestWithFSO.java
index 25b5a4b15d4..f9aa275ef75 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeyCommitRequestWithFSO.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMKeyCommitRequestWithFSO.java
@@ -245,7 +245,9 @@ public OMClientResponse validateAndUpdateCache(OzoneManager
ozoneManager, Execut
validateAtomicRewrite(keyToDelete, omKeyInfo, auditMap);
// Optimistic locking validation has passed. Now set the rewrite fields
to null so they are
// not persisted in the key table.
- omKeyInfo.setExpectedDataGeneration(null);
+ omKeyInfo = omKeyInfo.toBuilder()
+ .setExpectedDataGeneration(null)
+ .build();
long correctedSpace = omKeyInfo.getReplicatedSize();
// if keyToDelete isn't null, usedNamespace shouldn't check and increase.
diff --git
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/key/TestOMKeyCommitRequest.java
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/key/TestOMKeyCommitRequest.java
index c64196c590f..de009bf8fe4 100644
---
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/key/TestOMKeyCommitRequest.java
+++
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/key/TestOMKeyCommitRequest.java
@@ -274,7 +274,6 @@ public void testAtomicRewrite() throws Exception {
assertEquals(OK, omClientResponse.getOMResponse().getStatus());
OmKeyInfo committedKey = closedKeyTable.get(getOzonePathKey());
- assertNull(committedKey.getExpectedDataGeneration());
// Generation should be changed
assertNotEquals(closedKeyInfo.getGeneration(),
committedKey.getGeneration());
assertEquals(acls, committedKey.getAcls());
@@ -312,7 +311,6 @@ public void testAtomicCreateIfNotExistsCommitKeyAbsent()
throws Exception {
OmKeyInfo committedKey = closedKeyTable.get(getOzonePathKey());
assertNotNull(committedKey);
- assertNull(committedKey.getExpectedDataGeneration());
}
@Test
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]