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. 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}. The array to wrap. 082 */ 083 public SimplePositionedMutableByteRange(byte[] bytes) { 084 set(bytes); 085 } 086 087 /** 088 * Create a new {@code PositionedByteRange} over the provided {@code bytes}. The array to wrap. 089 * The offset into {@code bytes} considered the beginning of this range. The length of this range. 090 */ 091 public SimplePositionedMutableByteRange(byte[] bytes, int offset, int length) { 092 set(bytes, offset, length); 093 } 094 095 @Override 096 public PositionedByteRange unset() { 097 this.position = 0; 098 clearHashCache(); 099 bytes = null; 100 offset = 0; 101 length = 0; 102 return this; 103 } 104 105 @Override 106 public PositionedByteRange set(int capacity) { 107 this.position = 0; 108 super.set(capacity); 109 this.limit = capacity; 110 return this; 111 } 112 113 @Override 114 public PositionedByteRange set(byte[] bytes) { 115 this.position = 0; 116 super.set(bytes); 117 this.limit = bytes.length; 118 return this; 119 } 120 121 @Override 122 public PositionedByteRange set(byte[] bytes, int offset, int length) { 123 this.position = 0; 124 super.set(bytes, offset, length); 125 limit = length; 126 return this; 127 } 128 129 /** 130 * Update the beginning of this range. {@code offset + length} may not be greater than 131 * {@code bytes.length}. Resets {@code position} to 0. the new start of this range. 132 * @return this. 133 */ 134 @Override 135 public PositionedByteRange setOffset(int offset) { 136 this.position = 0; 137 super.setOffset(offset); 138 return this; 139 } 140 141 /** 142 * Update the length of this range. {@code offset + length} should not be greater than 143 * {@code bytes.length}. If {@code position} is greater than the new {@code length}, sets 144 * {@code position} to {@code length}. The new length of this range. 145 * @return this. 146 */ 147 @Override 148 public PositionedByteRange setLength(int length) { 149 this.position = Math.min(position, length); 150 super.setLength(length); 151 return this; 152 } 153 154 @Override 155 public PositionedByteRange put(byte val) { 156 put(position++, val); 157 return this; 158 } 159 160 @Override 161 public PositionedByteRange put(byte[] val) { 162 if (0 == val.length) return this; 163 return this.put(val, 0, val.length); 164 } 165 166 @Override 167 public PositionedByteRange put(byte[] val, int offset, int length) { 168 if (0 == length) return this; 169 put(position, val, offset, length); 170 this.position += length; 171 return this; 172 } 173 174 @Override 175 public PositionedByteRange get(int index, byte[] dst) { 176 super.get(index, dst); 177 return this; 178 } 179 180 @Override 181 public PositionedByteRange get(int index, byte[] dst, int offset, int length) { 182 super.get(index, dst, offset, length); 183 return this; 184 } 185 186 @Override 187 public PositionedByteRange put(int index, byte val) { 188 bytes[offset + index] = val; 189 return this; 190 } 191 192 @Override 193 public PositionedByteRange put(int index, byte[] val) { 194 if (0 == val.length) return this; 195 return put(index, val, 0, val.length); 196 } 197 198 @Override 199 public PositionedByteRange put(int index, byte[] val, int offset, int length) { 200 if (0 == length) return this; 201 System.arraycopy(val, offset, this.bytes, this.offset + index, length); 202 return this; 203 } 204 205 @Override 206 public PositionedByteRange deepCopy() { 207 SimplePositionedMutableByteRange clone = 208 new SimplePositionedMutableByteRange(deepCopyToNewArray()); 209 clone.position = this.position; 210 return clone; 211 } 212 213 @Override 214 public PositionedByteRange shallowCopy() { 215 SimplePositionedMutableByteRange clone = 216 new SimplePositionedMutableByteRange(bytes, offset, length); 217 clone.position = this.position; 218 return clone; 219 } 220 221 @Override 222 public PositionedByteRange shallowCopySubRange(int innerOffset, int copyLength) { 223 SimplePositionedMutableByteRange clone = 224 new SimplePositionedMutableByteRange(bytes, offset + innerOffset, copyLength); 225 clone.position = this.position; 226 return clone; 227 } 228 229 @Override 230 public PositionedByteRange putShort(short val) { 231 putShort(position, val); 232 position += Bytes.SIZEOF_SHORT; 233 return this; 234 } 235 236 @Override 237 public PositionedByteRange putInt(int val) { 238 putInt(position, val); 239 position += Bytes.SIZEOF_INT; 240 return this; 241 } 242 243 @Override 244 public PositionedByteRange putLong(long val) { 245 putLong(position, val); 246 position += Bytes.SIZEOF_LONG; 247 return this; 248 } 249 250 @Override 251 public int putVLong(long val) { 252 int len = putVLong(position, val); 253 position += len; 254 return len; 255 } 256 257 @Override 258 public PositionedByteRange putShort(int index, short val) { 259 // This writing is same as BB's putShort. When byte[] is wrapped in a BB and 260 // call putShort(), 261 // one can get the same result. 262 bytes[offset + index + 1] = (byte) val; 263 val >>= 8; 264 bytes[offset + index] = (byte) val; 265 clearHashCache(); 266 return this; 267 } 268 269 @Override 270 public PositionedByteRange putInt(int index, int val) { 271 // This writing is same as BB's putInt. When byte[] is wrapped in a BB and 272 // call getInt(), one 273 // can get the same result. 274 for (int i = Bytes.SIZEOF_INT - 1; i > 0; i--) { 275 bytes[offset + index + i] = (byte) val; 276 val >>>= 8; 277 } 278 bytes[offset + index] = (byte) val; 279 clearHashCache(); 280 return this; 281 } 282 283 @Override 284 public PositionedByteRange putLong(int index, long val) { 285 // This writing is same as BB's putLong. When byte[] is wrapped in a BB and 286 // call putLong(), one 287 // can get the same result. 288 for (int i = Bytes.SIZEOF_LONG - 1; i > 0; i--) { 289 bytes[offset + index + i] = (byte) val; 290 val >>>= 8; 291 } 292 bytes[offset + index] = (byte) val; 293 clearHashCache(); 294 return this; 295 } 296 297 // Copied from com.google.protobuf.CodedOutputStream v2.5.0 writeRawVarint64 298 @Override 299 public int putVLong(int index, long val) { 300 int rPos = 0; 301 while (true) { 302 if ((val & ~0x7F) == 0) { 303 bytes[offset + index + rPos] = (byte) val; 304 break; 305 } else { 306 bytes[offset + index + rPos] = (byte) ((val & 0x7F) | 0x80); 307 val >>>= 7; 308 } 309 rPos++; 310 } 311 clearHashCache(); 312 return rPos + 1; 313 } 314 // end copied from protobuf 315 316}