001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018// The portion of this file denoted by 'Copied from com.google.protobuf.CodedOutputStream' 019// is from Protocol Buffers v2.5.0 under the following license 020// 021// Protocol Buffers - Google's data interchange format 022// Copyright 2008 Google Inc. All rights reserved. 023// https://developers.google.com/protocol-buffers/ 024// 025// Redistribution and use in source and binary forms, with or without 026// modification, are permitted provided that the following conditions are 027// met: 028// 029// * Redistributions of source code must retain the above copyright 030// notice, this list of conditions and the following disclaimer. 031// * Redistributions in binary form must reproduce the above 032// copyright notice, this list of conditions and the following disclaimer 033// in the documentation and/or other materials provided with the 034// distribution. 035// * Neither the name of Google Inc. nor the names of its 036// contributors may be used to endorse or promote products derived from 037// this software without specific prior written permission. 038// 039// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 040// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 041// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 042// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 043// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 044// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 045// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 046// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 047// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 048// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 049// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 050package org.apache.hadoop.hbase.util; 051 052import org.apache.yetus.audience.InterfaceAudience; 053 054/** 055 * Extends the basic {@link AbstractPositionedByteRange} implementation with position support and it 056 * is a mutable version. {@code position} is considered transient, not fundamental to the definition 057 * of the range, and does not participate in {@link #compareTo(ByteRange)}, {@link #hashCode()}, or 058 * {@link #equals(Object)}. {@code Position} is retained by copy operations. 059 */ 060@InterfaceAudience.Public 061@edu.umd.cs.findbugs.annotations.SuppressWarnings("EQ_DOESNT_OVERRIDE_EQUALS") 062public class SimplePositionedMutableByteRange extends AbstractPositionedByteRange { 063 /** 064 * Create a new {@code PositionedByteRange} lacking a backing array and with an undefined 065 * viewport. 066 */ 067 public SimplePositionedMutableByteRange() { 068 super(); 069 } 070 071 /** 072 * Create a new {@code PositionedByteRange} over a new backing array of size {@code capacity}. The 073 * range's offset and length are 0 and {@code capacity}, respectively. n * the size of the backing 074 * array. 075 */ 076 public SimplePositionedMutableByteRange(int capacity) { 077 this(new byte[capacity]); 078 } 079 080 /** 081 * Create a new {@code PositionedByteRange} over the provided {@code bytes}. n * The array to 082 * wrap. 083 */ 084 public SimplePositionedMutableByteRange(byte[] bytes) { 085 set(bytes); 086 } 087 088 /** 089 * Create a new {@code PositionedByteRange} over the provided {@code bytes}. n * The array to 090 * wrap. n * The offset into {@code bytes} considered the beginning of this range. n * The length 091 * of this range. 092 */ 093 public SimplePositionedMutableByteRange(byte[] bytes, int offset, int length) { 094 set(bytes, offset, length); 095 } 096 097 @Override 098 public PositionedByteRange unset() { 099 this.position = 0; 100 clearHashCache(); 101 bytes = null; 102 offset = 0; 103 length = 0; 104 return this; 105 } 106 107 @Override 108 public PositionedByteRange set(int capacity) { 109 this.position = 0; 110 super.set(capacity); 111 this.limit = capacity; 112 return this; 113 } 114 115 @Override 116 public PositionedByteRange set(byte[] bytes) { 117 this.position = 0; 118 super.set(bytes); 119 this.limit = bytes.length; 120 return this; 121 } 122 123 @Override 124 public PositionedByteRange set(byte[] bytes, int offset, int length) { 125 this.position = 0; 126 super.set(bytes, offset, length); 127 limit = length; 128 return this; 129 } 130 131 /** 132 * Update the beginning of this range. {@code offset + length} may not be greater than 133 * {@code bytes.length}. Resets {@code position} to 0. n * the new start of this range. 134 * @return this. 135 */ 136 @Override 137 public PositionedByteRange setOffset(int offset) { 138 this.position = 0; 139 super.setOffset(offset); 140 return this; 141 } 142 143 /** 144 * Update the length of this range. {@code offset + length} should not be greater than 145 * {@code bytes.length}. If {@code position} is greater than the new {@code length}, sets 146 * {@code position} to {@code length}. n * The new length of this range. 147 * @return this. 148 */ 149 @Override 150 public PositionedByteRange setLength(int length) { 151 this.position = Math.min(position, length); 152 super.setLength(length); 153 return this; 154 } 155 156 @Override 157 public PositionedByteRange put(byte val) { 158 put(position++, val); 159 return this; 160 } 161 162 @Override 163 public PositionedByteRange put(byte[] val) { 164 if (0 == val.length) return this; 165 return this.put(val, 0, val.length); 166 } 167 168 @Override 169 public PositionedByteRange put(byte[] val, int offset, int length) { 170 if (0 == length) return this; 171 put(position, val, offset, length); 172 this.position += length; 173 return this; 174 } 175 176 @Override 177 public PositionedByteRange get(int index, byte[] dst) { 178 super.get(index, dst); 179 return this; 180 } 181 182 @Override 183 public PositionedByteRange get(int index, byte[] dst, int offset, int length) { 184 super.get(index, dst, offset, length); 185 return this; 186 } 187 188 @Override 189 public PositionedByteRange put(int index, byte val) { 190 bytes[offset + index] = val; 191 return this; 192 } 193 194 @Override 195 public PositionedByteRange put(int index, byte[] val) { 196 if (0 == val.length) return this; 197 return put(index, val, 0, val.length); 198 } 199 200 @Override 201 public PositionedByteRange put(int index, byte[] val, int offset, int length) { 202 if (0 == length) return this; 203 System.arraycopy(val, offset, this.bytes, this.offset + index, length); 204 return this; 205 } 206 207 @Override 208 public PositionedByteRange deepCopy() { 209 SimplePositionedMutableByteRange clone = 210 new SimplePositionedMutableByteRange(deepCopyToNewArray()); 211 clone.position = this.position; 212 return clone; 213 } 214 215 @Override 216 public PositionedByteRange shallowCopy() { 217 SimplePositionedMutableByteRange clone = 218 new SimplePositionedMutableByteRange(bytes, offset, length); 219 clone.position = this.position; 220 return clone; 221 } 222 223 @Override 224 public PositionedByteRange shallowCopySubRange(int innerOffset, int copyLength) { 225 SimplePositionedMutableByteRange clone = 226 new SimplePositionedMutableByteRange(bytes, offset + innerOffset, copyLength); 227 clone.position = this.position; 228 return clone; 229 } 230 231 @Override 232 public PositionedByteRange putShort(short val) { 233 putShort(position, val); 234 position += Bytes.SIZEOF_SHORT; 235 return this; 236 } 237 238 @Override 239 public PositionedByteRange putInt(int val) { 240 putInt(position, val); 241 position += Bytes.SIZEOF_INT; 242 return this; 243 } 244 245 @Override 246 public PositionedByteRange putLong(long val) { 247 putLong(position, val); 248 position += Bytes.SIZEOF_LONG; 249 return this; 250 } 251 252 @Override 253 public int putVLong(long val) { 254 int len = putVLong(position, val); 255 position += len; 256 return len; 257 } 258 259 @Override 260 public PositionedByteRange putShort(int index, short val) { 261 // This writing is same as BB's putShort. When byte[] is wrapped in a BB and 262 // call putShort(), 263 // one can get the same result. 264 bytes[offset + index + 1] = (byte) val; 265 val >>= 8; 266 bytes[offset + index] = (byte) val; 267 clearHashCache(); 268 return this; 269 } 270 271 @Override 272 public PositionedByteRange putInt(int index, int val) { 273 // This writing is same as BB's putInt. When byte[] is wrapped in a BB and 274 // call getInt(), one 275 // can get the same result. 276 for (int i = Bytes.SIZEOF_INT - 1; i > 0; i--) { 277 bytes[offset + index + i] = (byte) val; 278 val >>>= 8; 279 } 280 bytes[offset + index] = (byte) val; 281 clearHashCache(); 282 return this; 283 } 284 285 @Override 286 public PositionedByteRange putLong(int index, long val) { 287 // This writing is same as BB's putLong. When byte[] is wrapped in a BB and 288 // call putLong(), one 289 // can get the same result. 290 for (int i = Bytes.SIZEOF_LONG - 1; i > 0; i--) { 291 bytes[offset + index + i] = (byte) val; 292 val >>>= 8; 293 } 294 bytes[offset + index] = (byte) val; 295 clearHashCache(); 296 return this; 297 } 298 299 // Copied from com.google.protobuf.CodedOutputStream v2.5.0 writeRawVarint64 300 @Override 301 public int putVLong(int index, long val) { 302 int rPos = 0; 303 while (true) { 304 if ((val & ~0x7F) == 0) { 305 bytes[offset + index + rPos] = (byte) val; 306 break; 307 } else { 308 bytes[offset + index + rPos] = (byte) ((val & 0x7F) | 0x80); 309 val >>>= 7; 310 } 311 rPos++; 312 } 313 clearHashCache(); 314 return rPos + 1; 315 } 316 // end copied from protobuf 317 318}