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 019package org.apache.hadoop.hbase.io; 020 021import org.apache.hadoop.hbase.util.Bytes; 022import org.apache.yetus.audience.InterfaceAudience; 023 024/** 025 * Represents an interval of version timestamps. Presumes timestamps between 026 * {@link #INITIAL_MIN_TIMESTAMP} and {@link #INITIAL_MAX_TIMESTAMP} only. Gets freaked out if 027 * passed a timestamp that is < {@link #INITIAL_MIN_TIMESTAMP}, 028 * <p> 029 * Evaluated according to minStamp <= timestamp < maxStamp or [minStamp,maxStamp) in interval 030 * notation. 031 * <p> 032 * Can be returned and read by clients. Should not be directly created by clients. Thus, all 033 * constructors are purposely @InterfaceAudience.Private. 034 * <p> 035 * Immutable. Thread-safe. 036 */ 037@InterfaceAudience.Public 038public class TimeRange { 039 public static final long INITIAL_MIN_TIMESTAMP = 0L; 040 public static final long INITIAL_MAX_TIMESTAMP = Long.MAX_VALUE; 041 private static final TimeRange ALL_TIME = new TimeRange(INITIAL_MIN_TIMESTAMP, 042 INITIAL_MAX_TIMESTAMP); 043 044 public static TimeRange allTime() { 045 return ALL_TIME; 046 } 047 048 public static TimeRange at(long ts) { 049 if (ts < 0 || ts == Long.MAX_VALUE) { 050 throw new IllegalArgumentException("invalid ts:" + ts); 051 } 052 return new TimeRange(ts, ts + 1); 053 } 054 055 /** 056 * Represents the time interval [minStamp, Long.MAX_VALUE) 057 * @param minStamp the minimum timestamp value, inclusive 058 */ 059 public static TimeRange from(long minStamp) { 060 check(minStamp, INITIAL_MAX_TIMESTAMP); 061 return new TimeRange(minStamp, INITIAL_MAX_TIMESTAMP); 062 } 063 064 /** 065 * Represents the time interval [0, maxStamp) 066 * @param maxStamp the minimum timestamp value, exclusive 067 */ 068 public static TimeRange until(long maxStamp) { 069 check(INITIAL_MIN_TIMESTAMP, maxStamp); 070 return new TimeRange(INITIAL_MIN_TIMESTAMP, maxStamp); 071 } 072 073 /** 074 * Represents the time interval [minStamp, maxStamp) 075 * @param minStamp the minimum timestamp, inclusive 076 * @param maxStamp the maximum timestamp, exclusive 077 */ 078 public static TimeRange between(long minStamp, long maxStamp) { 079 check(minStamp, maxStamp); 080 return new TimeRange(minStamp, maxStamp); 081 } 082 083 private final long minStamp; 084 private final long maxStamp; 085 private final boolean allTime; 086 087 /** 088 * Default constructor. 089 * Represents interval [0, Long.MAX_VALUE) (allTime) 090 * @deprecated This is made @InterfaceAudience.Private in the 2.0 line and above and may be 091 * changed to private or removed in 3.0. 092 */ 093 @Deprecated 094 @InterfaceAudience.Private 095 public TimeRange() { 096 this(INITIAL_MIN_TIMESTAMP, INITIAL_MAX_TIMESTAMP); 097 } 098 099 /** 100 * Represents interval [minStamp, Long.MAX_VALUE) 101 * @param minStamp the minimum timestamp value, inclusive 102 * @deprecated This is made @InterfaceAudience.Private in the 2.0 line and above and may be 103 * changed to private or removed in 3.0. 104 */ 105 @Deprecated 106 @InterfaceAudience.Private 107 public TimeRange(long minStamp) { 108 this(minStamp, INITIAL_MAX_TIMESTAMP); 109 } 110 111 /** 112 * Represents interval [minStamp, Long.MAX_VALUE) 113 * @param minStamp the minimum timestamp value, inclusive 114 * @deprecated This is made @InterfaceAudience.Private in the 2.0 line and above and may be 115 * changed to private or removed in 3.0. 116 */ 117 @Deprecated 118 @InterfaceAudience.Private 119 public TimeRange(byte [] minStamp) { 120 this(Bytes.toLong(minStamp)); 121 } 122 123 /** 124 * Represents interval [minStamp, maxStamp) 125 * @param minStamp the minimum timestamp, inclusive 126 * @param maxStamp the maximum timestamp, exclusive 127 * @deprecated This is made @InterfaceAudience.Private in the 2.0 line and above and may be 128 * changed to private or removed in 3.0. 129 */ 130 @Deprecated 131 @InterfaceAudience.Private 132 public TimeRange(byte [] minStamp, byte [] maxStamp) { 133 this(Bytes.toLong(minStamp), Bytes.toLong(maxStamp)); 134 } 135 136 /** 137 * Represents interval [minStamp, maxStamp) 138 * @param minStamp the minimum timestamp, inclusive 139 * @param maxStamp the maximum timestamp, exclusive 140 * @throws IllegalArgumentException if either <0, 141 * @deprecated This is made @InterfaceAudience.Private in the 2.0 line and above and may be 142 * changed to private or removed in 3.0. 143 */ 144 @Deprecated 145 @InterfaceAudience.Private 146 public TimeRange(long minStamp, long maxStamp) { 147 check(minStamp, maxStamp); 148 this.minStamp = minStamp; 149 this.maxStamp = maxStamp; 150 this.allTime = isAllTime(minStamp, maxStamp); 151 } 152 153 private static boolean isAllTime(long minStamp, long maxStamp) { 154 return minStamp == INITIAL_MIN_TIMESTAMP && maxStamp == INITIAL_MAX_TIMESTAMP; 155 } 156 157 private static void check(long minStamp, long maxStamp) { 158 if (minStamp < 0 || maxStamp < 0) { 159 throw new IllegalArgumentException("Timestamp cannot be negative. minStamp:" + minStamp 160 + ", maxStamp:" + maxStamp); 161 } 162 if (maxStamp < minStamp) { 163 throw new IllegalArgumentException("maxStamp is smaller than minStamp"); 164 } 165 } 166 167 /** 168 * @return the smallest timestamp that should be considered 169 */ 170 public long getMin() { 171 return minStamp; 172 } 173 174 /** 175 * @return the biggest timestamp that should be considered 176 */ 177 public long getMax() { 178 return maxStamp; 179 } 180 181 /** 182 * Check if it is for all time 183 * @return true if it is for all time 184 */ 185 public boolean isAllTime() { 186 return allTime; 187 } 188 189 /** 190 * Check if the specified timestamp is within this TimeRange. 191 * <p> 192 * Returns true if within interval [minStamp, maxStamp), false if not. 193 * @param bytes timestamp to check 194 * @param offset offset into the bytes 195 * @return true if within TimeRange, false if not 196 * @deprecated This is made @InterfaceAudience.Private in the 2.0 line and above and may be 197 * changed to private or removed in 3.0. Use {@link #withinTimeRange(long)} instead 198 */ 199 @Deprecated 200 public boolean withinTimeRange(byte [] bytes, int offset) { 201 if (allTime) { 202 return true; 203 } 204 return withinTimeRange(Bytes.toLong(bytes, offset)); 205 } 206 207 /** 208 * Check if the specified timestamp is within this TimeRange. 209 * <p> 210 * Returns true if within interval [minStamp, maxStamp), false 211 * if not. 212 * @param timestamp timestamp to check 213 * @return true if within TimeRange, false if not 214 */ 215 public boolean withinTimeRange(long timestamp) { 216 assert timestamp >= 0; 217 if (this.allTime) { 218 return true; 219 } 220 // check if >= minStamp 221 return (minStamp <= timestamp && timestamp < maxStamp); 222 } 223 224 /** 225 * Check if the range has any overlap with TimeRange 226 * @param tr TimeRange 227 * @return True if there is overlap, false otherwise 228 */ 229 // This method came from TimeRangeTracker. We used to go there for this function but better 230 // to come here to the immutable, unsynchronized datastructure at read time. 231 public boolean includesTimeRange(final TimeRange tr) { 232 if (this.allTime) { 233 return true; 234 } 235 assert tr.getMin() >= 0; 236 return getMin() < tr.getMax() && getMax() >= tr.getMin(); 237 } 238 239 /** 240 * Check if the specified timestamp is within or after this TimeRange. 241 * <p> 242 * Returns true if greater than minStamp, false if not. 243 * @param timestamp timestamp to check 244 * @return true if within or after TimeRange, false if not 245 */ 246 public boolean withinOrAfterTimeRange(long timestamp) { 247 assert timestamp >= 0; 248 if (allTime) { 249 return true; 250 } 251 // check if >= minStamp 252 return timestamp >= minStamp; 253 } 254 255 /** 256 * Compare the timestamp to timerange. 257 * @return -1 if timestamp is less than timerange, 258 * 0 if timestamp is within timerange, 259 * 1 if timestamp is greater than timerange 260 */ 261 public int compare(long timestamp) { 262 assert timestamp >= 0; 263 if (this.allTime) { 264 return 0; 265 } 266 if (timestamp < minStamp) { 267 return -1; 268 } 269 return timestamp >= maxStamp? 1: 0; 270 } 271 272 @Override 273 public String toString() { 274 StringBuilder sb = new StringBuilder(); 275 sb.append("maxStamp="); 276 sb.append(this.maxStamp); 277 sb.append(", minStamp="); 278 sb.append(this.minStamp); 279 return sb.toString(); 280 } 281}