View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.regionserver;
20  
21  import java.io.DataInput;
22  import java.io.DataOutput;
23  import java.io.IOException;
24  
25  import org.apache.hadoop.hbase.Cell;
26  import org.apache.hadoop.hbase.CellUtil;
27  import org.apache.hadoop.hbase.classification.InterfaceAudience;
28  import org.apache.hadoop.hbase.io.TimeRange;
29  import org.apache.hadoop.io.Writable;
30  
31  /**
32   * Stores the minimum and maximum timestamp values (both are inclusive).
33   * Can be used to find if any given time range overlaps with its time range
34   * MemStores use this class to track its minimum and maximum timestamps.
35   * When writing StoreFiles, this information is stored in meta blocks and used
36   * at read time to match against the required TimeRange.
37   */
38  @InterfaceAudience.Private
39  public class TimeRangeTracker implements Writable {
40    static final long INITIAL_MINIMUM_TIMESTAMP = Long.MAX_VALUE;
41    long minimumTimestamp = INITIAL_MINIMUM_TIMESTAMP;
42    long maximumTimestamp = -1;
43  
44    /**
45     * Default constructor.
46     * Initializes TimeRange to be null
47     */
48    public TimeRangeTracker() {}
49  
50    /**
51     * Copy Constructor
52     * @param trt source TimeRangeTracker
53     */
54    public TimeRangeTracker(final TimeRangeTracker trt) {
55      set(trt.getMinimumTimestamp(), trt.getMaximumTimestamp());
56    }
57  
58    public TimeRangeTracker(long minimumTimestamp, long maximumTimestamp) {
59      set(minimumTimestamp, maximumTimestamp);
60    }
61  
62    private void set(final long min, final long max) {
63      this.minimumTimestamp = min;
64      this.maximumTimestamp = max;
65    }
66  
67    /**
68     * @param l
69     * @return True if we initialized values
70     */
71    private boolean init(final long l) {
72      if (this.minimumTimestamp != INITIAL_MINIMUM_TIMESTAMP) return false;
73      set(l, l);
74      return true;
75    }
76  
77    /**
78     * Update the current TimestampRange to include the timestamp from Cell
79     * If the Key is of type DeleteColumn or DeleteFamily, it includes the
80     * entire time range from 0 to timestamp of the key.
81     * @param cell the Cell to include
82     */
83    public void includeTimestamp(final Cell cell) {
84      includeTimestamp(cell.getTimestamp());
85      if (CellUtil.isDeleteColumnOrFamily(cell)) {
86        includeTimestamp(0);
87      }
88    }
89  
90    /**
91     * If required, update the current TimestampRange to include timestamp
92     * @param timestamp the timestamp value to include
93     */
94    @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="MT_CORRECTNESS",
95        justification="Intentional")
96    void includeTimestamp(final long timestamp) {
97      // Do test outside of synchronization block.  Synchronization in here can be problematic
98      // when many threads writing one Store -- they can all pile up trying to add in here.
99      // Happens when doing big write upload where we are hammering on one region.
100     if (timestamp < this.minimumTimestamp) {
101       synchronized (this) {
102         if (!init(timestamp)) {
103           if (timestamp < this.minimumTimestamp) {
104             this.minimumTimestamp = timestamp;
105           }
106         }
107       }
108     } else if (timestamp > this.maximumTimestamp) {
109       synchronized (this) {
110         if (!init(timestamp)) {
111           if (this.maximumTimestamp < timestamp) {
112             this.maximumTimestamp =  timestamp;
113           }
114         }
115       }
116     }
117   }
118 
119   /**
120    * Check if the range has any overlap with TimeRange
121    * @param tr TimeRange
122    * @return True if there is overlap, false otherwise
123    */
124   public synchronized boolean includesTimeRange(final TimeRange tr) {
125     return (this.minimumTimestamp < tr.getMax() && this.maximumTimestamp >= tr.getMin());
126   }
127 
128   /**
129    * @return the minimumTimestamp
130    */
131   public synchronized long getMinimumTimestamp() {
132     return minimumTimestamp;
133   }
134 
135   /**
136    * @return the maximumTimestamp
137    */
138   public synchronized long getMaximumTimestamp() {
139     return maximumTimestamp;
140   }
141 
142   public synchronized void write(final DataOutput out) throws IOException {
143     out.writeLong(minimumTimestamp);
144     out.writeLong(maximumTimestamp);
145   }
146 
147   public synchronized void readFields(final DataInput in) throws IOException {
148     this.minimumTimestamp = in.readLong();
149     this.maximumTimestamp = in.readLong();
150   }
151 
152   @Override
153   public synchronized String toString() {
154     return "[" + minimumTimestamp + "," + maximumTimestamp + "]";
155   }
156 }