Index: src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java (revision 11356) +++ src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java (working copy) @@ -2996,7 +2996,7 @@ // TODO: Use RWCC to make this set of increments atomic to reads byte [] row = increment.getRow(); checkRow(row); - TimeRange tr = increment.getTimeRange(); + Map familyTimeRanges = increment.getTimeRangeMap(); boolean flush = false; WALEdit walEdits = null; List allKVs = new ArrayList(increment.numColumns()); @@ -3020,6 +3020,8 @@ for (Map.Entry column : family.getValue().entrySet()) { get.addColumn(family.getKey(), column.getKey()); } + // Use default TimeRange unless one specified for this family + TimeRange tr = increment.getTimeRange(family.getKey()); get.setTimeRange(tr.getMin(), tr.getMax()); List results = getLastIncrement(get); Index: src/main/java/org/apache/hadoop/hbase/io/TimeRange.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/io/TimeRange.java (revision 11356) +++ src/main/java/org/apache/hadoop/hbase/io/TimeRange.java (working copy) @@ -148,6 +148,14 @@ } /** + * Checks if this TimeRange is set for all time, ie. [0, Max.Long). + * @return true if TimeRange is all time, false if not + */ + public boolean isAllTime() { + return (minStamp == 0 && maxStamp == Long.MAX_VALUE); + } + + /** * Compare the timestamp to timerange * @param timestamp * @return -1 if timestamp is less than timerange, Index: src/main/java/org/apache/hadoop/hbase/client/Increment.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/client/Increment.java (revision 11356) +++ src/main/java/org/apache/hadoop/hbase/client/Increment.java (working copy) @@ -52,6 +52,8 @@ private TimeRange tr = new TimeRange(); private Map> familyMap = new TreeMap>(Bytes.BYTES_COMPARATOR); + private Map timeRangeMap = + new TreeMap(Bytes.BYTES_COMPARATOR); /** Constructor for Writable. DO NOT USE */ public Increment() {} @@ -154,6 +156,30 @@ } /** + * Gets the TimeRange used for this increment and for the specified family. + *

+ * If an individual TimeRange was set on this family, it will be returned. If + * not, this will return the TimeRange set across all families. + * @param family + * @return TimeRange + */ + public TimeRange getTimeRange(byte [] family) { + if (timeRangeMap.containsKey(family)) return timeRangeMap.get(family); + return this.tr; + } + + /** + * Gets the TimeRange map of each family to its specified TimeRange. + *

+ * This will only contain entries for families who have had an explicit + * TimeRange set. + * @return + */ + public Map getTimeRangeMap() { + return this.timeRangeMap; + } + + /** * Sets the TimeRange to be used on the Get for this increment. *

* This is useful for when you have counters that only last for specific @@ -162,6 +188,10 @@ * some performance with a more optimal Get operation. *

* This range is used as [minStamp, maxStamp). + *

+ * This will set the TimeRange on all families and columns in this Increment + * operation. To set the TimeRange on individual families, use + * {@link #setTimeRange(byte[], long, long)}. * @param minStamp minimum timestamp value, inclusive * @param maxStamp maximum timestamp value, exclusive * @throws IOException if invalid time range @@ -174,6 +204,25 @@ } /** + * Sets the TimeRange to be used on the Get for this increment, but only for + * the specified family. If incrementing multiple families, you may want to + * specify different TimeRanges for each family. Use this method to do so. + *

+ * See {@link #setTimeRange(long, long)} for more information. + * @param family the family to set this TimeRange on + * @param minStamp minimum timestamp value, inclusive + * @param maxStamp maximum timestamp value, exclusive + * @throws IOException if invalid time range + * @return this + */ + public Increment setTimeRange(byte [] family, long minStamp, long maxStamp) + throws IOException { + TimeRange tr = new TimeRange(minStamp, maxStamp); + timeRangeMap.put(family, tr); + return this; + } + + /** * Method for retrieving the keys in the familyMap * @return keys in the current familyMap */ @@ -230,6 +279,11 @@ sb.append(", no columns set to be incremented"); return sb.toString(); } + if (!this.tr.isAllTime()) { + sb.append(", timerange=["); + sb.append(this.tr.toString()); + sb.append("]"); + } sb.append(", families="); boolean moreThanOne = false; for(Map.Entry> entry : @@ -258,6 +312,11 @@ } sb.append("}"); } + if (timeRangeMap.containsKey(entry.getKey())) { + sb.append(", timerange=["); + sb.append(timeRangeMap.get(entry.getKey()).toString()); + sb.append("]"); + } } sb.append("}"); return sb.toString(); @@ -296,6 +355,13 @@ } this.familyMap.put(family, set); } + int numTimeRangeFamilies = in.readInt(); + for (int i=0;i entry : timeRangeMap.entrySet()) { + Bytes.writeByteArray(out, entry.getKey()); + entry.getValue().write(out); + } } }