HBASE-26921 Rewrite the counting cells part in TestMultiVersions (#4316)
[hbase.git] / hbase-server / src / main / java / org / apache / hadoop / hbase / wal / WALKeyImpl.java
blob4c3fc4edc787fad8310d694d0aca12a9184a7527
1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org.apache.hadoop.hbase.wal;
20 import java.io.IOException;
21 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.NavigableMap;
26 import java.util.TreeMap;
27 import java.util.UUID;
28 import org.apache.hadoop.hbase.HBaseInterfaceAudience;
29 import org.apache.hadoop.hbase.HConstants;
30 import org.apache.hadoop.hbase.TableName;
31 import org.apache.hadoop.hbase.regionserver.MultiVersionConcurrencyControl;
32 import org.apache.hadoop.hbase.regionserver.SequenceId;
33 import org.apache.hadoop.hbase.regionserver.wal.CompressionContext;
34 import org.apache.hadoop.hbase.regionserver.wal.WALCellCodec;
35 import org.apache.hadoop.hbase.util.Bytes;
36 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
37 import org.apache.yetus.audience.InterfaceAudience;
39 import org.apache.hbase.thirdparty.com.google.protobuf.ByteString;
41 import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos;
42 import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos;
43 import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.FamilyScope;
44 import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.ScopeType;
46 /**
47 * Default implementation of Key for an Entry in the WAL.
48 * For internal use only though Replication needs to have access.
50 * The log intermingles edits to many tables and rows, so each log entry
51 * identifies the appropriate table and row. Within a table and row, they're
52 * also sorted.
54 * <p>Some Transactional edits (START, COMMIT, ABORT) will not have an associated row.
57 // TODO: Key and WALEdit are never used separately, or in one-to-many relation, for practical
58 // purposes. They need to be merged into WALEntry.
59 @InterfaceAudience.LimitedPrivate({HBaseInterfaceAudience.REPLICATION})
60 public class WALKeyImpl implements WALKey {
61 public static final WALKeyImpl EMPTY_WALKEYIMPL = new WALKeyImpl();
63 public MultiVersionConcurrencyControl getMvcc() {
64 return mvcc;
67 /**
68 * Use it to complete mvcc transaction. This WALKeyImpl was part of
69 * (the transaction is started when you call append; see the comment on FSHLog#append). To
70 * complete call
71 * {@link MultiVersionConcurrencyControl#complete(MultiVersionConcurrencyControl.WriteEntry)}
72 * or {@link MultiVersionConcurrencyControl#complete(MultiVersionConcurrencyControl.WriteEntry)}
73 * @return A WriteEntry gotten from local WAL subsystem.
74 * @see #setWriteEntry(MultiVersionConcurrencyControl.WriteEntry)
76 public MultiVersionConcurrencyControl.WriteEntry getWriteEntry() {
77 return this.writeEntry;
80 public void setWriteEntry(MultiVersionConcurrencyControl.WriteEntry writeEntry) {
81 assert this.writeEntry == null;
82 this.writeEntry = writeEntry;
83 // Set our sequenceid now using WriteEntry.
84 this.sequenceId = writeEntry.getWriteNumber();
87 private byte [] encodedRegionName;
89 private TableName tablename;
91 /**
92 * SequenceId for this edit. Set post-construction at write-to-WAL time. Until then it is
93 * NO_SEQUENCE_ID. Change it so multiple threads can read it -- e.g. access is synchronized.
95 private long sequenceId;
97 /**
98 * Used during WAL replay; the sequenceId of the edit when it came into the system.
100 private long origLogSeqNum = 0;
102 /** Time at which this edit was written. */
103 private long writeTime;
105 /** The first element in the list is the cluster id on which the change has originated */
106 private List<UUID> clusterIds;
108 private NavigableMap<byte[], Integer> replicationScope;
110 private long nonceGroup = HConstants.NO_NONCE;
111 private long nonce = HConstants.NO_NONCE;
112 private MultiVersionConcurrencyControl mvcc;
115 * Set in a way visible to multiple threads; e.g. synchronized getter/setters.
117 private MultiVersionConcurrencyControl.WriteEntry writeEntry;
119 private Map<String, byte[]> extendedAttributes;
121 public WALKeyImpl() {
122 init(null, null, 0L, HConstants.LATEST_TIMESTAMP,
123 new ArrayList<>(), HConstants.NO_NONCE, HConstants.NO_NONCE, null, null, null);
126 public WALKeyImpl(final NavigableMap<byte[], Integer> replicationScope) {
127 init(null, null, 0L, HConstants.LATEST_TIMESTAMP,
128 new ArrayList<>(), HConstants.NO_NONCE, HConstants.NO_NONCE, null, replicationScope, null);
131 @InterfaceAudience.Private
132 public WALKeyImpl(final byte[] encodedRegionName, final TableName tablename, long logSeqNum,
133 final long now, UUID clusterId) {
134 List<UUID> clusterIds = new ArrayList<>(1);
135 clusterIds.add(clusterId);
136 init(encodedRegionName, tablename, logSeqNum, now, clusterIds, HConstants.NO_NONCE,
137 HConstants.NO_NONCE, null, null, null);
140 @InterfaceAudience.Private
141 public WALKeyImpl(final byte[] encodedRegionName, final TableName tablename, long logSeqNum,
142 final long now, UUID clusterId, MultiVersionConcurrencyControl mvcc) {
143 List<UUID> clusterIds = new ArrayList<>(1);
144 clusterIds.add(clusterId);
145 init(encodedRegionName, tablename, logSeqNum, now, clusterIds, HConstants.NO_NONCE,
146 HConstants.NO_NONCE, mvcc, null, null);
149 // TODO: Fix being able to pass in sequenceid.
150 public WALKeyImpl(final byte[] encodedRegionName, final TableName tablename, final long now) {
151 init(encodedRegionName,
152 tablename,
153 NO_SEQUENCE_ID,
154 now,
155 EMPTY_UUIDS,
156 HConstants.NO_NONCE,
157 HConstants.NO_NONCE,
158 null, null, null);
161 // TODO: Fix being able to pass in sequenceid.
162 public WALKeyImpl(final byte[] encodedRegionName, final TableName tablename, final long now,
163 final NavigableMap<byte[], Integer> replicationScope) {
164 init(encodedRegionName, tablename, NO_SEQUENCE_ID, now, EMPTY_UUIDS, HConstants.NO_NONCE,
165 HConstants.NO_NONCE, null, replicationScope, null);
168 public WALKeyImpl(final byte[] encodedRegionName, final TableName tablename, final long now,
169 MultiVersionConcurrencyControl mvcc, final NavigableMap<byte[], Integer> replicationScope) {
170 init(encodedRegionName, tablename, NO_SEQUENCE_ID, now, EMPTY_UUIDS, HConstants.NO_NONCE,
171 HConstants.NO_NONCE, mvcc, replicationScope, null);
174 public WALKeyImpl(final byte[] encodedRegionName, final TableName tablename, final long now,
175 MultiVersionConcurrencyControl mvcc,
176 final NavigableMap<byte[], Integer> replicationScope,
177 Map<String, byte[]> extendedAttributes) {
178 init(encodedRegionName, tablename, NO_SEQUENCE_ID, now, EMPTY_UUIDS, HConstants.NO_NONCE,
179 HConstants.NO_NONCE, mvcc, replicationScope, extendedAttributes);
182 public WALKeyImpl(final byte[] encodedRegionName,
183 final TableName tablename,
184 final long now,
185 MultiVersionConcurrencyControl mvcc) {
186 init(encodedRegionName,
187 tablename,
188 NO_SEQUENCE_ID,
189 now,
190 EMPTY_UUIDS,
191 HConstants.NO_NONCE,
192 HConstants.NO_NONCE,
193 mvcc, null, null);
197 * Copy constructor that takes in an existing WALKeyImpl plus some extended attributes.
198 * Intended for coprocessors to add annotations to a system-generated WALKey
199 * for persistence to the WAL.
200 * @param key Key to be copied into this new key
201 * @param extendedAttributes Extra attributes to copy into the new key
203 public WALKeyImpl(WALKeyImpl key,
204 Map<String, byte[]> extendedAttributes){
205 init(key.getEncodedRegionName(), key.getTableName(), key.getSequenceId(),
206 key.getWriteTime(), key.getClusterIds(), key.getNonceGroup(), key.getNonce(),
207 key.getMvcc(), key.getReplicationScopes(), extendedAttributes);
212 * Copy constructor that takes in an existing WALKey, the extra WALKeyImpl fields that the
213 * parent interface is missing, plus some extended attributes. Intended
214 * for coprocessors to add annotations to a system-generated WALKey for
215 * persistence to the WAL.
217 public WALKeyImpl(WALKey key,
218 List<UUID> clusterIds,
219 MultiVersionConcurrencyControl mvcc,
220 final NavigableMap<byte[], Integer> replicationScopes,
221 Map<String, byte[]> extendedAttributes){
222 init(key.getEncodedRegionName(), key.getTableName(), key.getSequenceId(),
223 key.getWriteTime(), clusterIds, key.getNonceGroup(), key.getNonce(),
224 mvcc, replicationScopes, extendedAttributes);
228 * Create the log key for writing to somewhere.
229 * We maintain the tablename mainly for debugging purposes.
230 * A regionName is always a sub-table object.
231 * <p>Used by log splitting and snapshots.
233 * @param encodedRegionName Encoded name of the region as returned by
234 * <code>HRegionInfo#getEncodedNameAsBytes()</code>.
235 * @param tablename - name of table
236 * @param logSeqNum - log sequence number
237 * @param now Time at which this edit was written.
238 * @param clusterIds the clusters that have consumed the change(used in Replication)
239 * @param nonceGroup the nonceGroup
240 * @param nonce the nonce
241 * @param mvcc the mvcc associate the WALKeyImpl
242 * @param replicationScope the non-default replication scope
243 * associated with the region's column families
245 // TODO: Fix being able to pass in sequenceid.
246 public WALKeyImpl(final byte[] encodedRegionName, final TableName tablename, long logSeqNum,
247 final long now, List<UUID> clusterIds, long nonceGroup, long nonce,
248 MultiVersionConcurrencyControl mvcc, final NavigableMap<byte[], Integer> replicationScope) {
249 init(encodedRegionName, tablename, logSeqNum, now, clusterIds, nonceGroup, nonce, mvcc,
250 replicationScope, null);
254 * Create the log key for writing to somewhere.
255 * We maintain the tablename mainly for debugging purposes.
256 * A regionName is always a sub-table object.
257 * <p>Used by log splitting and snapshots.
259 * @param encodedRegionName Encoded name of the region as returned by
260 * <code>HRegionInfo#getEncodedNameAsBytes()</code>.
261 * @param tablename - name of table
262 * @param logSeqNum - log sequence number
263 * @param now Time at which this edit was written.
264 * @param clusterIds the clusters that have consumed the change(used in Replication)
266 // TODO: Fix being able to pass in sequenceid.
267 public WALKeyImpl(final byte[] encodedRegionName,
268 final TableName tablename,
269 long logSeqNum,
270 final long now,
271 List<UUID> clusterIds,
272 long nonceGroup,
273 long nonce,
274 MultiVersionConcurrencyControl mvcc) {
275 init(encodedRegionName, tablename, logSeqNum, now, clusterIds, nonceGroup,
276 nonce, mvcc, null, null);
280 * Create the log key for writing to somewhere.
281 * We maintain the tablename mainly for debugging purposes.
282 * A regionName is always a sub-table object.
284 * @param encodedRegionName Encoded name of the region as returned by
285 * <code>HRegionInfo#getEncodedNameAsBytes()</code>.
286 * @param tablename the tablename
287 * @param now Time at which this edit was written.
288 * @param clusterIds the clusters that have consumed the change(used in Replication)
289 * @param nonceGroup
290 * @param nonce
291 * @param mvcc mvcc control used to generate sequence numbers and control read/write points
293 public WALKeyImpl(final byte[] encodedRegionName, final TableName tablename,
294 final long now, List<UUID> clusterIds, long nonceGroup,
295 final long nonce, final MultiVersionConcurrencyControl mvcc) {
296 init(encodedRegionName, tablename, NO_SEQUENCE_ID, now, clusterIds, nonceGroup, nonce, mvcc,
297 null, null);
301 * Create the log key for writing to somewhere.
302 * We maintain the tablename mainly for debugging purposes.
303 * A regionName is always a sub-table object.
305 * @param encodedRegionName Encoded name of the region as returned by
306 * <code>HRegionInfo#getEncodedNameAsBytes()</code>.
307 * @param tablename
308 * @param now Time at which this edit was written.
309 * @param clusterIds the clusters that have consumed the change(used in Replication)
310 * @param nonceGroup the nonceGroup
311 * @param nonce the nonce
312 * @param mvcc mvcc control used to generate sequence numbers and control read/write points
313 * @param replicationScope the non-default replication scope of the column families
315 public WALKeyImpl(final byte[] encodedRegionName, final TableName tablename,
316 final long now, List<UUID> clusterIds, long nonceGroup,
317 final long nonce, final MultiVersionConcurrencyControl mvcc,
318 NavigableMap<byte[], Integer> replicationScope) {
319 init(encodedRegionName, tablename, NO_SEQUENCE_ID, now, clusterIds, nonceGroup, nonce, mvcc,
320 replicationScope, null);
324 * Create the log key for writing to somewhere.
325 * We maintain the tablename mainly for debugging purposes.
326 * A regionName is always a sub-table object.
328 * @param encodedRegionName Encoded name of the region as returned by
329 * <code>HRegionInfo#getEncodedNameAsBytes()</code>.
330 * @param tablename
331 * @param logSeqNum
332 * @param nonceGroup
333 * @param nonce
335 // TODO: Fix being able to pass in sequenceid.
336 public WALKeyImpl(final byte[] encodedRegionName,
337 final TableName tablename,
338 long logSeqNum,
339 long nonceGroup,
340 long nonce,
341 final MultiVersionConcurrencyControl mvcc) {
342 init(encodedRegionName,
343 tablename,
344 logSeqNum,
345 EnvironmentEdgeManager.currentTime(),
346 EMPTY_UUIDS,
347 nonceGroup,
348 nonce,
349 mvcc, null, null);
352 public WALKeyImpl(final byte[] encodedRegionName, final TableName tablename,
353 final long now, List<UUID> clusterIds, long nonceGroup,
354 final long nonce, final MultiVersionConcurrencyControl mvcc,
355 NavigableMap<byte[], Integer> replicationScope,
356 Map<String, byte[]> extendedAttributes){
357 init(encodedRegionName,
358 tablename,
359 NO_SEQUENCE_ID,
360 now,
361 clusterIds,
362 nonceGroup,
363 nonce,
364 mvcc, replicationScope, extendedAttributes);
367 @InterfaceAudience.Private
368 protected void init(final byte[] encodedRegionName,
369 final TableName tablename,
370 long logSeqNum,
371 final long now,
372 List<UUID> clusterIds,
373 long nonceGroup,
374 long nonce,
375 MultiVersionConcurrencyControl mvcc,
376 NavigableMap<byte[], Integer> replicationScope,
377 Map<String, byte[]> extendedAttributes) {
378 this.sequenceId = logSeqNum;
379 this.writeTime = now;
380 this.clusterIds = clusterIds;
381 this.encodedRegionName = encodedRegionName;
382 this.tablename = tablename;
383 this.nonceGroup = nonceGroup;
384 this.nonce = nonce;
385 this.mvcc = mvcc;
386 if (logSeqNum != NO_SEQUENCE_ID) {
387 setSequenceId(logSeqNum);
389 this.replicationScope = replicationScope;
390 this.extendedAttributes = extendedAttributes;
393 // For deserialization. DO NOT USE. See setWriteEntry below.
394 @InterfaceAudience.Private
395 protected void setSequenceId(long sequenceId) {
396 this.sequenceId = sequenceId;
399 /** @return encoded region name */
400 @Override
401 public byte [] getEncodedRegionName() {
402 return encodedRegionName;
405 /** @return table name */
406 @Override
407 public TableName getTableName() {
408 return tablename;
412 * Used to set original sequenceId for WALKeyImpl during WAL replay
414 public void setOrigLogSeqNum(final long sequenceId) {
415 this.origLogSeqNum = sequenceId;
419 * Return a positive long if current WALKeyImpl is created from a replay edit; a replay edit is an
420 * edit that came in when replaying WALs of a crashed server.
421 * @return original sequence number of the WALEdit
423 @Override
424 public long getOrigLogSeqNum() {
425 return this.origLogSeqNum;
429 * SequenceId is only available post WAL-assign. Calls before this will get you a
430 * {@link SequenceId#NO_SEQUENCE_ID}. See the comment on FSHLog#append and #getWriteNumber in this
431 * method for more on when this sequenceId comes available.
432 * @return long the new assigned sequence number
434 @Override
435 public long getSequenceId() {
436 return this.sequenceId;
440 * @return the write time
442 @Override
443 public long getWriteTime() {
444 return this.writeTime;
447 public NavigableMap<byte[], Integer> getReplicationScopes() {
448 return replicationScope;
451 /** @return The nonce group */
452 @Override
453 public long getNonceGroup() {
454 return nonceGroup;
457 /** @return The nonce */
458 @Override
459 public long getNonce() {
460 return nonce;
463 private void setReplicationScope(NavigableMap<byte[], Integer> replicationScope) {
464 this.replicationScope = replicationScope;
467 public void clearReplicationScope() {
468 setReplicationScope(null);
472 * Marks that the cluster with the given clusterId has consumed the change
474 public void addClusterId(UUID clusterId) {
475 if (!clusterIds.contains(clusterId)) {
476 clusterIds.add(clusterId);
481 * @return the set of cluster Ids that have consumed the change
483 public List<UUID> getClusterIds() {
484 return clusterIds;
488 * @return the cluster id on which the change has originated. It there is no such cluster, it
489 * returns DEFAULT_CLUSTER_ID (cases where replication is not enabled)
491 @Override
492 public UUID getOriginatingClusterId(){
493 return clusterIds.isEmpty()? HConstants.DEFAULT_CLUSTER_ID: clusterIds.get(0);
496 @Override
497 public void addExtendedAttribute(String attributeKey, byte[] attributeValue){
498 if (extendedAttributes == null){
499 extendedAttributes = new HashMap<String, byte[]>();
501 extendedAttributes.put(attributeKey, attributeValue);
504 @Override
505 public byte[] getExtendedAttribute(String attributeKey){
506 return extendedAttributes != null ? extendedAttributes.get(attributeKey) : null;
509 @Override
510 public Map<String, byte[]> getExtendedAttributes(){
511 return extendedAttributes != null ? new HashMap<String, byte[]>(extendedAttributes) :
512 new HashMap<String, byte[]>();
515 @Override
516 public String toString() {
517 return tablename + "/" + Bytes.toString(encodedRegionName) + "/" + sequenceId;
520 @Override
521 public boolean equals(Object obj) {
522 if (this == obj) {
523 return true;
525 if (obj == null || getClass() != obj.getClass()) {
526 return false;
528 return compareTo((WALKey)obj) == 0;
531 @Override
532 public int hashCode() {
533 int result = Bytes.hashCode(this.encodedRegionName);
534 result = (int) (result ^ getSequenceId());
535 result = (int) (result ^ this.writeTime);
536 return result;
539 @Override
540 public int compareTo(WALKey o) {
541 int result = Bytes.compareTo(this.encodedRegionName, o.getEncodedRegionName());
542 if (result == 0) {
543 long sid = getSequenceId();
544 long otherSid = o.getSequenceId();
545 if (sid < otherSid) {
546 result = -1;
547 } else if (sid > otherSid) {
548 result = 1;
550 if (result == 0) {
551 if (this.writeTime < o.getWriteTime()) {
552 result = -1;
553 } else if (this.writeTime > o.getWriteTime()) {
554 return 1;
558 // why isn't cluster id accounted for?
559 return result;
563 * Drop this instance's tablename byte array and instead
564 * hold a reference to the provided tablename. This is not
565 * meant to be a general purpose setter - it's only used
566 * to collapse references to conserve memory.
568 void internTableName(TableName tablename) {
569 // We should not use this as a setter - only to swap
570 // in a new reference to the same table name.
571 assert tablename.equals(this.tablename);
572 this.tablename = tablename;
576 * Drop this instance's region name byte array and instead
577 * hold a reference to the provided region name. This is not
578 * meant to be a general purpose setter - it's only used
579 * to collapse references to conserve memory.
581 void internEncodedRegionName(byte []encodedRegionName) {
582 // We should not use this as a setter - only to swap
583 // in a new reference to the same table name.
584 assert Bytes.equals(this.encodedRegionName, encodedRegionName);
585 this.encodedRegionName = encodedRegionName;
588 public WALProtos.WALKey.Builder getBuilder(WALCellCodec.ByteStringCompressor compressor)
589 throws IOException {
590 WALProtos.WALKey.Builder builder = WALProtos.WALKey.newBuilder();
591 builder.setEncodedRegionName(
592 compressor.compress(this.encodedRegionName, CompressionContext.DictionaryIndex.REGION));
593 builder.setTableName(
594 compressor.compress(this.tablename.getName(), CompressionContext.DictionaryIndex.TABLE));
595 builder.setLogSequenceNumber(getSequenceId());
596 builder.setWriteTime(writeTime);
597 if (this.origLogSeqNum > 0) {
598 builder.setOrigSequenceNumber(this.origLogSeqNum);
600 if (this.nonce != HConstants.NO_NONCE) {
601 builder.setNonce(nonce);
603 if (this.nonceGroup != HConstants.NO_NONCE) {
604 builder.setNonceGroup(nonceGroup);
606 HBaseProtos.UUID.Builder uuidBuilder = HBaseProtos.UUID.newBuilder();
607 for (UUID clusterId : clusterIds) {
608 uuidBuilder.setLeastSigBits(clusterId.getLeastSignificantBits());
609 uuidBuilder.setMostSigBits(clusterId.getMostSignificantBits());
610 builder.addClusterIds(uuidBuilder.build());
612 if (replicationScope != null) {
613 for (Map.Entry<byte[], Integer> e : replicationScope.entrySet()) {
614 ByteString family =
615 compressor.compress(e.getKey(), CompressionContext.DictionaryIndex.FAMILY);
616 builder.addScopes(FamilyScope.newBuilder().setFamily(family)
617 .setScopeType(ScopeType.forNumber(e.getValue())));
620 if (extendedAttributes != null){
621 for (Map.Entry<String, byte[]> e : extendedAttributes.entrySet()){
622 WALProtos.Attribute attr = WALProtos.Attribute.newBuilder().
623 setKey(e.getKey()).setValue(compressor.compress(e.getValue(),
624 CompressionContext.DictionaryIndex.TABLE)).build();
625 builder.addExtendedAttributes(attr);
628 return builder;
631 public void readFieldsFromPb(WALProtos.WALKey walKey,
632 WALCellCodec.ByteStringUncompressor uncompressor) throws IOException {
633 this.encodedRegionName = uncompressor.uncompress(walKey.getEncodedRegionName(),
634 CompressionContext.DictionaryIndex.REGION);
635 byte[] tablenameBytes =
636 uncompressor.uncompress(walKey.getTableName(), CompressionContext.DictionaryIndex.TABLE);
637 this.tablename = TableName.valueOf(tablenameBytes);
638 clusterIds.clear();
639 for (HBaseProtos.UUID clusterId : walKey.getClusterIdsList()) {
640 clusterIds.add(new UUID(clusterId.getMostSigBits(), clusterId.getLeastSigBits()));
642 if (walKey.hasNonceGroup()) {
643 this.nonceGroup = walKey.getNonceGroup();
645 if (walKey.hasNonce()) {
646 this.nonce = walKey.getNonce();
648 this.replicationScope = null;
649 if (walKey.getScopesCount() > 0) {
650 this.replicationScope = new TreeMap<>(Bytes.BYTES_COMPARATOR);
651 for (FamilyScope scope : walKey.getScopesList()) {
652 byte[] family =
653 uncompressor.uncompress(scope.getFamily(), CompressionContext.DictionaryIndex.FAMILY);
654 this.replicationScope.put(family, scope.getScopeType().getNumber());
657 setSequenceId(walKey.getLogSequenceNumber());
658 this.writeTime = walKey.getWriteTime();
659 if (walKey.hasOrigSequenceNumber()) {
660 this.origLogSeqNum = walKey.getOrigSequenceNumber();
662 if (walKey.getExtendedAttributesCount() > 0){
663 this.extendedAttributes = new HashMap<>(walKey.getExtendedAttributesCount());
664 for (WALProtos.Attribute attr : walKey.getExtendedAttributesList()){
665 byte[] value =
666 uncompressor.uncompress(attr.getValue(), CompressionContext.DictionaryIndex.TABLE);
667 extendedAttributes.put(attr.getKey(), value);
672 @Override
673 public long estimatedSerializedSizeOf() {
674 long size = encodedRegionName != null ? encodedRegionName.length : 0;
675 size += tablename != null ? tablename.toBytes().length : 0;
676 if (clusterIds != null) {
677 size += 16 * clusterIds.size();
679 if (nonceGroup != HConstants.NO_NONCE) {
680 size += Bytes.SIZEOF_LONG; // nonce group
682 if (nonce != HConstants.NO_NONCE) {
683 size += Bytes.SIZEOF_LONG; // nonce
685 if (replicationScope != null) {
686 for (Map.Entry<byte[], Integer> scope: replicationScope.entrySet()) {
687 size += scope.getKey().length;
688 size += Bytes.SIZEOF_INT;
691 size += Bytes.SIZEOF_LONG; // sequence number
692 size += Bytes.SIZEOF_LONG; // write time
693 if (origLogSeqNum > 0) {
694 size += Bytes.SIZEOF_LONG; // original sequence number
696 return size;