1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.protobuf;
21
22
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.NavigableMap;
29 import java.util.UUID;
30
31 import com.google.protobuf.HBaseZeroCopyByteString;
32 import org.apache.hadoop.classification.InterfaceAudience;
33 import org.apache.hadoop.hbase.Cell;
34 import org.apache.hadoop.hbase.CellScanner;
35 import org.apache.hadoop.hbase.KeyValue;
36 import org.apache.hadoop.hbase.io.SizedCellScanner;
37 import org.apache.hadoop.hbase.ipc.PayloadCarryingRpcController;
38 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos;
39 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.AdminService;
40 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
41 import org.apache.hadoop.hbase.protobuf.generated.WALProtos;
42 import org.apache.hadoop.hbase.regionserver.wal.HLog;
43 import org.apache.hadoop.hbase.regionserver.wal.HLogKey;
44 import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
45 import org.apache.hadoop.hbase.util.Pair;
46
47 import com.google.protobuf.ServiceException;
48
49 @InterfaceAudience.Private
50 public class ReplicationProtbufUtil {
51
52
53
54
55
56
57
58 public static void replicateWALEntry(final AdminService.BlockingInterface admin,
59 final HLog.Entry[] entries) throws IOException {
60 Pair<AdminProtos.ReplicateWALEntryRequest, CellScanner> p =
61 buildReplicateWALEntryRequest(entries);
62 try {
63 PayloadCarryingRpcController controller = new PayloadCarryingRpcController(p.getSecond());
64 admin.replicateWALEntry(controller, p.getFirst());
65 } catch (ServiceException se) {
66 throw ProtobufUtil.getRemoteException(se);
67 }
68 }
69
70
71
72
73
74
75
76
77 public static Pair<AdminProtos.ReplicateWALEntryRequest, CellScanner>
78 buildReplicateWALEntryRequest(final HLog.Entry[] entries) {
79
80 List<List<? extends Cell>> allkvs = new ArrayList<List<? extends Cell>>(entries.length);
81 int size = 0;
82 WALProtos.FamilyScope.Builder scopeBuilder = WALProtos.FamilyScope.newBuilder();
83 AdminProtos.WALEntry.Builder entryBuilder = AdminProtos.WALEntry.newBuilder();
84 AdminProtos.ReplicateWALEntryRequest.Builder builder =
85 AdminProtos.ReplicateWALEntryRequest.newBuilder();
86 HBaseProtos.UUID.Builder uuidBuilder = HBaseProtos.UUID.newBuilder();
87 for (HLog.Entry entry: entries) {
88 entryBuilder.clear();
89 WALProtos.WALKey.Builder keyBuilder = entryBuilder.getKeyBuilder();
90 HLogKey key = entry.getKey();
91 keyBuilder.setEncodedRegionName(
92 HBaseZeroCopyByteString.wrap(key.getEncodedRegionName()));
93 keyBuilder.setTableName(HBaseZeroCopyByteString.wrap(key.getTablename().getName()));
94 keyBuilder.setLogSequenceNumber(key.getLogSeqNum());
95 keyBuilder.setWriteTime(key.getWriteTime());
96 for(UUID clusterId : key.getClusterIds()) {
97 uuidBuilder.setLeastSigBits(clusterId.getLeastSignificantBits());
98 uuidBuilder.setMostSigBits(clusterId.getMostSignificantBits());
99 keyBuilder.addClusterIds(uuidBuilder.build());
100 }
101 WALEdit edit = entry.getEdit();
102 NavigableMap<byte[], Integer> scopes = key.getScopes();
103 if (scopes != null && !scopes.isEmpty()) {
104 for (Map.Entry<byte[], Integer> scope: scopes.entrySet()) {
105 scopeBuilder.setFamily(HBaseZeroCopyByteString.wrap(scope.getKey()));
106 WALProtos.ScopeType scopeType =
107 WALProtos.ScopeType.valueOf(scope.getValue().intValue());
108 scopeBuilder.setScopeType(scopeType);
109 keyBuilder.addScopes(scopeBuilder.build());
110 }
111 }
112 List<KeyValue> kvs = edit.getKeyValues();
113
114 for (KeyValue kv: kvs) {
115 size += kv.getLength();
116 }
117
118 allkvs.add(kvs);
119
120 entryBuilder.setAssociatedCellCount(kvs.size());
121 builder.addEntry(entryBuilder.build());
122 }
123 return new Pair<AdminProtos.ReplicateWALEntryRequest, CellScanner>(builder.build(),
124 getCellScanner(allkvs, size));
125 }
126
127
128
129
130
131 static CellScanner getCellScanner(final List<List<? extends Cell>> cells, final int size) {
132 return new SizedCellScanner() {
133 private final Iterator<List<? extends Cell>> entries = cells.iterator();
134 private Iterator<? extends Cell> currentIterator = null;
135 private Cell currentCell;
136
137 @Override
138 public Cell current() {
139 return this.currentCell;
140 }
141
142 @Override
143 public boolean advance() {
144 if (this.currentIterator == null) {
145 if (!this.entries.hasNext()) return false;
146 this.currentIterator = this.entries.next().iterator();
147 }
148 if (this.currentIterator.hasNext()) {
149 this.currentCell = this.currentIterator.next();
150 return true;
151 }
152 this.currentCell = null;
153 this.currentIterator = null;
154 return advance();
155 }
156
157 @Override
158 public long heapSize() {
159 return size;
160 }
161 };
162 }
163 }