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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  */
18 package org.apache.hadoop.hbase;
19 
20 import java.io.IOException;
21 
22 import org.apache.hadoop.hbase.classification.InterfaceAudience;
23 import org.apache.hadoop.hbase.io.HeapSize;
24 import org.apache.hadoop.hbase.util.ClassSize;
25 
26 /**
27  * This can be used when a Cell has to change with addition/removal of one or more tags. This is an
28  * efficient way to do so in which only the tags bytes part need to recreated and copied. All other
29  * parts, refer to the original Cell.
30  */
31 @InterfaceAudience.Private
32 public class TagRewriteCell implements Cell, SettableSequenceId, SettableTimestamp, HeapSize {
33 
34   private Cell cell;
35   private byte[] tags;
36 
37   /**
38    * @param cell The original Cell which it rewrites
39    * @param tags the tags bytes. The array suppose to contain the tags bytes alone.
40    */
TagRewriteCell(Cell cell, byte[] tags)41   public TagRewriteCell(Cell cell, byte[] tags) {
42     assert cell instanceof SettableSequenceId;
43     assert cell instanceof SettableTimestamp;
44     assert tags != null;
45     this.cell = cell;
46     this.tags = tags;
47     // tag offset will be treated as 0 and length this.tags.length
48     if (this.cell instanceof TagRewriteCell) {
49       // Cleaning the ref so that the byte[] can be GCed
50       ((TagRewriteCell) this.cell).tags = null;
51     }
52   }
53 
54   @Override
getRowArray()55   public byte[] getRowArray() {
56     return cell.getRowArray();
57   }
58 
59   @Override
getRowOffset()60   public int getRowOffset() {
61     return cell.getRowOffset();
62   }
63 
64   @Override
getRowLength()65   public short getRowLength() {
66     return cell.getRowLength();
67   }
68 
69   @Override
getFamilyArray()70   public byte[] getFamilyArray() {
71     return cell.getFamilyArray();
72   }
73 
74   @Override
getFamilyOffset()75   public int getFamilyOffset() {
76     return cell.getFamilyOffset();
77   }
78 
79   @Override
getFamilyLength()80   public byte getFamilyLength() {
81     return cell.getFamilyLength();
82   }
83 
84   @Override
getQualifierArray()85   public byte[] getQualifierArray() {
86     return cell.getQualifierArray();
87   }
88 
89   @Override
getQualifierOffset()90   public int getQualifierOffset() {
91     return cell.getQualifierOffset();
92   }
93 
94   @Override
getQualifierLength()95   public int getQualifierLength() {
96     return cell.getQualifierLength();
97   }
98 
99   @Override
getTimestamp()100   public long getTimestamp() {
101     return cell.getTimestamp();
102   }
103 
104   @Override
getTypeByte()105   public byte getTypeByte() {
106     return cell.getTypeByte();
107   }
108 
109   @Override
110   @Deprecated
getMvccVersion()111   public long getMvccVersion() {
112     return getSequenceId();
113   }
114 
115   @Override
getSequenceId()116   public long getSequenceId() {
117     return cell.getSequenceId();
118   }
119 
120   @Override
getValueArray()121   public byte[] getValueArray() {
122     return cell.getValueArray();
123   }
124 
125   @Override
getValueOffset()126   public int getValueOffset() {
127     return cell.getValueOffset();
128   }
129 
130   @Override
getValueLength()131   public int getValueLength() {
132     return cell.getValueLength();
133   }
134 
135   @Override
getTagsArray()136   public byte[] getTagsArray() {
137     return this.tags;
138   }
139 
140   @Override
getTagsOffset()141   public int getTagsOffset() {
142     return 0;
143   }
144 
145   @Override
getTagsLength()146   public int getTagsLength() {
147     if (null == this.tags) {
148       // Nulled out tags array optimization in constructor
149       return 0;
150     }
151     return this.tags.length;
152   }
153 
154   @Override
155   @Deprecated
getValue()156   public byte[] getValue() {
157     return cell.getValue();
158   }
159 
160   @Override
161   @Deprecated
getFamily()162   public byte[] getFamily() {
163     return cell.getFamily();
164   }
165 
166   @Override
167   @Deprecated
getQualifier()168   public byte[] getQualifier() {
169     return cell.getQualifier();
170   }
171 
172   @Override
173   @Deprecated
getRow()174   public byte[] getRow() {
175     return cell.getRow();
176   }
177 
178   @Override
heapSize()179   public long heapSize() {
180     long sum = CellUtil.estimatedHeapSizeOf(cell) - cell.getTagsLength();
181     sum += ClassSize.OBJECT;// this object itself
182     sum += (2 * ClassSize.REFERENCE);// pointers to cell and tags array
183     if (this.tags != null) {
184       sum += ClassSize.align(ClassSize.ARRAY);// "tags"
185       sum += this.tags.length;
186     }
187     return sum;
188   }
189 
190   @Override
setTimestamp(long ts)191   public void setTimestamp(long ts) throws IOException {
192     // The incoming cell is supposed to be SettableTimestamp type.
193     CellUtil.setTimestamp(cell, ts);
194   }
195 
196   @Override
setTimestamp(byte[] ts, int tsOffset)197   public void setTimestamp(byte[] ts, int tsOffset) throws IOException {
198     // The incoming cell is supposed to be SettableTimestamp type.
199     CellUtil.setTimestamp(cell, ts, tsOffset);
200   }
201 
202   @Override
setSequenceId(long seqId)203   public void setSequenceId(long seqId) throws IOException {
204     // The incoming cell is supposed to be SettableSequenceId type.
205     CellUtil.setSequenceId(cell, seqId);
206   }
207 }
208