HBASE-18753 Introduce the unsynchronized TimeRangeTracker
This commit is contained in:
parent
6cf647a0df
commit
2cc1ea3d2e
|
@ -20,7 +20,6 @@
|
||||||
|
|
||||||
package org.apache.hadoop.hbase.util;
|
package org.apache.hadoop.hbase.util;
|
||||||
|
|
||||||
import org.apache.hadoop.hbase.shaded.com.google.common.annotations.VisibleForTesting;
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
@ -30,6 +29,8 @@ import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.apache.yetus.audience.InterfaceAudience;
|
import org.apache.yetus.audience.InterfaceAudience;
|
||||||
|
|
||||||
|
import org.apache.hadoop.hbase.shaded.com.google.common.annotations.VisibleForTesting;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for determining the "size" of a class, an attempt to calculate the
|
* Class for determining the "size" of a class, an attempt to calculate the
|
||||||
|
@ -128,8 +129,8 @@ public class ClassSize {
|
||||||
/** Overhead for timerange */
|
/** Overhead for timerange */
|
||||||
public static final int TIMERANGE;
|
public static final int TIMERANGE;
|
||||||
|
|
||||||
/** Overhead for TimeRangeTracker */
|
/** Overhead for SyncTimeRangeTracker */
|
||||||
public static final int TIMERANGE_TRACKER;
|
public static final int SYNC_TIMERANGE_TRACKER;
|
||||||
|
|
||||||
/** Overhead for CellSkipListSet */
|
/** Overhead for CellSkipListSet */
|
||||||
public static final int CELL_SET;
|
public static final int CELL_SET;
|
||||||
|
@ -325,7 +326,7 @@ public class ClassSize {
|
||||||
|
|
||||||
TIMERANGE = align(ClassSize.OBJECT + Bytes.SIZEOF_LONG * 2 + Bytes.SIZEOF_BOOLEAN);
|
TIMERANGE = align(ClassSize.OBJECT + Bytes.SIZEOF_LONG * 2 + Bytes.SIZEOF_BOOLEAN);
|
||||||
|
|
||||||
TIMERANGE_TRACKER = align(ClassSize.OBJECT + 2 * REFERENCE);
|
SYNC_TIMERANGE_TRACKER = align(ClassSize.OBJECT + 2 * REFERENCE);
|
||||||
CELL_SET = align(OBJECT + REFERENCE);
|
CELL_SET = align(OBJECT + REFERENCE);
|
||||||
|
|
||||||
STORE_SERVICES = align(OBJECT + REFERENCE + ATOMIC_LONG);
|
STORE_SERVICES = align(OBJECT + REFERENCE + ATOMIC_LONG);
|
||||||
|
|
|
@ -399,7 +399,7 @@ public class TestHFileOutputFormat2 {
|
||||||
assertNotNull(range);
|
assertNotNull(range);
|
||||||
|
|
||||||
// unmarshall and check values.
|
// unmarshall and check values.
|
||||||
TimeRangeTracker timeRangeTracker = new TimeRangeTracker();
|
TimeRangeTracker timeRangeTracker = TimeRangeTracker.create(TimeRangeTracker.Type.SYNC);
|
||||||
Writables.copyWritable(range, timeRangeTracker);
|
Writables.copyWritable(range, timeRangeTracker);
|
||||||
LOG.info(timeRangeTracker.getMin() +
|
LOG.info(timeRangeTracker.getMin() +
|
||||||
"...." + timeRangeTracker.getMax());
|
"...." + timeRangeTracker.getMax());
|
||||||
|
|
|
@ -18,19 +18,20 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hadoop.hbase.regionserver;
|
package org.apache.hadoop.hbase.regionserver;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.yetus.audience.InterfaceAudience;
|
|
||||||
import org.apache.hadoop.hbase.Cell;
|
|
||||||
import org.apache.hadoop.hbase.CellComparator;
|
|
||||||
import org.apache.hadoop.hbase.io.TimeRange;
|
|
||||||
import org.apache.hadoop.hbase.shaded.com.google.common.annotations.VisibleForTesting;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.hadoop.hbase.Cell;
|
||||||
|
import org.apache.hadoop.hbase.CellComparator;
|
||||||
|
import org.apache.hadoop.hbase.io.TimeRange;
|
||||||
|
import org.apache.yetus.audience.InterfaceAudience;
|
||||||
|
|
||||||
|
import org.apache.hadoop.hbase.shaded.com.google.common.annotations.VisibleForTesting;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The CompositeImmutableSegments is created as a collection of ImmutableSegments and supports
|
* The CompositeImmutableSegments is created as a collection of ImmutableSegments and supports
|
||||||
* the interface of a single ImmutableSegments.
|
* the interface of a single ImmutableSegments.
|
||||||
|
@ -51,7 +52,7 @@ public class CompositeImmutableSegment extends ImmutableSegment {
|
||||||
public CompositeImmutableSegment(CellComparator comparator, List<ImmutableSegment> segments) {
|
public CompositeImmutableSegment(CellComparator comparator, List<ImmutableSegment> segments) {
|
||||||
super(comparator);
|
super(comparator);
|
||||||
this.segments = segments;
|
this.segments = segments;
|
||||||
this.timeRangeTracker = new TimeRangeTracker();
|
this.timeRangeTracker = TimeRangeTracker.create(TimeRangeTracker.Type.SYNC);
|
||||||
for (ImmutableSegment s : segments) {
|
for (ImmutableSegment s : segments) {
|
||||||
this.timeRangeTracker.includeTimestamp(s.getTimeRangeTracker().getMax());
|
this.timeRangeTracker.includeTimestamp(s.getTimeRangeTracker().getMax());
|
||||||
this.timeRangeTracker.includeTimestamp(s.getTimeRangeTracker().getMin());
|
this.timeRangeTracker.includeTimestamp(s.getTimeRangeTracker().getMin());
|
||||||
|
|
|
@ -31,10 +31,10 @@ import org.apache.hadoop.hbase.CellComparator;
|
||||||
import org.apache.hadoop.hbase.CellUtil;
|
import org.apache.hadoop.hbase.CellUtil;
|
||||||
import org.apache.hadoop.hbase.KeyValue;
|
import org.apache.hadoop.hbase.KeyValue;
|
||||||
import org.apache.hadoop.hbase.KeyValueUtil;
|
import org.apache.hadoop.hbase.KeyValueUtil;
|
||||||
import org.apache.yetus.audience.InterfaceAudience;
|
|
||||||
import org.apache.hadoop.hbase.io.TimeRange;
|
import org.apache.hadoop.hbase.io.TimeRange;
|
||||||
import org.apache.hadoop.hbase.util.Bytes;
|
import org.apache.hadoop.hbase.util.Bytes;
|
||||||
import org.apache.hadoop.hbase.util.ClassSize;
|
import org.apache.hadoop.hbase.util.ClassSize;
|
||||||
|
import org.apache.yetus.audience.InterfaceAudience;
|
||||||
|
|
||||||
import org.apache.hadoop.hbase.shaded.com.google.common.annotations.VisibleForTesting;
|
import org.apache.hadoop.hbase.shaded.com.google.common.annotations.VisibleForTesting;
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ public abstract class Segment {
|
||||||
+ Bytes.SIZEOF_LONG // minSequenceId
|
+ Bytes.SIZEOF_LONG // minSequenceId
|
||||||
+ Bytes.SIZEOF_BOOLEAN); // tagsPresent
|
+ Bytes.SIZEOF_BOOLEAN); // tagsPresent
|
||||||
public final static long DEEP_OVERHEAD = FIXED_OVERHEAD + ClassSize.ATOMIC_REFERENCE
|
public final static long DEEP_OVERHEAD = FIXED_OVERHEAD + ClassSize.ATOMIC_REFERENCE
|
||||||
+ ClassSize.CELL_SET + 2 * ClassSize.ATOMIC_LONG + ClassSize.TIMERANGE_TRACKER;
|
+ ClassSize.CELL_SET + 2 * ClassSize.ATOMIC_LONG + ClassSize.SYNC_TIMERANGE_TRACKER;
|
||||||
|
|
||||||
private AtomicReference<CellSet> cellSet= new AtomicReference<>();
|
private AtomicReference<CellSet> cellSet= new AtomicReference<>();
|
||||||
private final CellComparator comparator;
|
private final CellComparator comparator;
|
||||||
|
@ -73,7 +73,7 @@ public abstract class Segment {
|
||||||
this.comparator = comparator;
|
this.comparator = comparator;
|
||||||
this.dataSize = new AtomicLong(0);
|
this.dataSize = new AtomicLong(0);
|
||||||
this.heapSize = new AtomicLong(0);
|
this.heapSize = new AtomicLong(0);
|
||||||
this.timeRangeTracker = new TimeRangeTracker();
|
this.timeRangeTracker = TimeRangeTracker.create(TimeRangeTracker.Type.SYNC);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This constructor is used to create empty Segments.
|
// This constructor is used to create empty Segments.
|
||||||
|
@ -85,7 +85,7 @@ public abstract class Segment {
|
||||||
this.dataSize = new AtomicLong(0);
|
this.dataSize = new AtomicLong(0);
|
||||||
this.heapSize = new AtomicLong(0);
|
this.heapSize = new AtomicLong(0);
|
||||||
this.tagsPresent = false;
|
this.tagsPresent = false;
|
||||||
this.timeRangeTracker = new TimeRangeTracker();
|
this.timeRangeTracker = TimeRangeTracker.create(TimeRangeTracker.Type.SYNC);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Segment(Segment segment) {
|
protected Segment(Segment segment) {
|
||||||
|
|
|
@ -131,7 +131,7 @@ public class StoreFileWriter implements CellSink, ShipperListener {
|
||||||
// TODO: put the state of the TRT on the TRT; i.e. make a read-only version (TimeRange) when
|
// TODO: put the state of the TRT on the TRT; i.e. make a read-only version (TimeRange) when
|
||||||
// it no longer writable.
|
// it no longer writable.
|
||||||
this.timeRangeTrackerSet = trt != null;
|
this.timeRangeTrackerSet = trt != null;
|
||||||
this.timeRangeTracker = this.timeRangeTrackerSet? trt: new TimeRangeTracker();
|
this.timeRangeTracker = this.timeRangeTrackerSet? trt: TimeRangeTracker.create(TimeRangeTracker.Type.NON_SYNC);
|
||||||
// TODO : Change all writers to be specifically created for compaction context
|
// TODO : Change all writers to be specifically created for compaction context
|
||||||
writer = HFile.getWriterFactory(conf, cacheConf)
|
writer = HFile.getWriterFactory(conf, cacheConf)
|
||||||
.withPath(fs, path)
|
.withPath(fs, path)
|
||||||
|
|
|
@ -25,17 +25,17 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
import org.apache.hadoop.hbase.Cell;
|
import org.apache.hadoop.hbase.Cell;
|
||||||
import org.apache.hadoop.hbase.CellUtil;
|
import org.apache.hadoop.hbase.CellUtil;
|
||||||
import org.apache.yetus.audience.InterfaceAudience;
|
|
||||||
import org.apache.hadoop.hbase.io.TimeRange;
|
import org.apache.hadoop.hbase.io.TimeRange;
|
||||||
import org.apache.hadoop.hbase.util.Writables;
|
import org.apache.hadoop.hbase.util.Writables;
|
||||||
import org.apache.hadoop.io.Writable;
|
import org.apache.hadoop.io.Writable;
|
||||||
|
import org.apache.yetus.audience.InterfaceAudience;
|
||||||
|
|
||||||
|
import org.apache.hadoop.hbase.shaded.com.google.common.annotations.VisibleForTesting;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores minimum and maximum timestamp values, it is [minimumTimestamp, maximumTimestamp] in
|
* Stores minimum and maximum timestamp values, it is [minimumTimestamp, maximumTimestamp] in
|
||||||
* interval notation.
|
* interval notation.
|
||||||
* Use this class at write-time ONLY. Too much synchronization to use at read time
|
* Use this class at write-time ONLY. Too much synchronization to use at read time
|
||||||
* (TODO: there are two scenarios writing, once when lots of concurrency as part of memstore
|
|
||||||
* updates but then later we can make one as part of a compaction when there is only one thread
|
|
||||||
* involved -- consider making different version, the synchronized and the unsynchronized).
|
|
||||||
* Use {@link TimeRange} at read time instead of this. See toTimeRange() to make TimeRange to use.
|
* Use {@link TimeRange} at read time instead of this. See toTimeRange() to make TimeRange to use.
|
||||||
* MemStores use this class to track minimum and maximum timestamps. The TimeRangeTracker made by
|
* MemStores use this class to track minimum and maximum timestamps. The TimeRangeTracker made by
|
||||||
* the MemStore is passed to the StoreFile for it to write out as part a flush in the the file
|
* the MemStore is passed to the StoreFile for it to write out as part a flush in the the file
|
||||||
|
@ -44,33 +44,55 @@ import org.apache.hadoop.io.Writable;
|
||||||
* at read time via an instance of {@link TimeRange} to test if Cells fit the StoreFile TimeRange.
|
* at read time via an instance of {@link TimeRange} to test if Cells fit the StoreFile TimeRange.
|
||||||
*/
|
*/
|
||||||
@InterfaceAudience.Private
|
@InterfaceAudience.Private
|
||||||
public class TimeRangeTracker implements Writable {
|
public abstract class TimeRangeTracker implements Writable {
|
||||||
|
|
||||||
|
public enum Type {
|
||||||
|
// thread-unsafe
|
||||||
|
NON_SYNC,
|
||||||
|
// thread-safe
|
||||||
|
SYNC
|
||||||
|
}
|
||||||
|
|
||||||
static final long INITIAL_MIN_TIMESTAMP = Long.MAX_VALUE;
|
static final long INITIAL_MIN_TIMESTAMP = Long.MAX_VALUE;
|
||||||
static final long INITIAL_MAX_TIMESTAMP = -1L;
|
static final long INITIAL_MAX_TIMESTAMP = -1L;
|
||||||
|
|
||||||
AtomicLong minimumTimestamp = new AtomicLong(INITIAL_MIN_TIMESTAMP);
|
public static TimeRangeTracker create(Type type) {
|
||||||
AtomicLong maximumTimestamp = new AtomicLong(INITIAL_MAX_TIMESTAMP);
|
switch (type) {
|
||||||
|
case NON_SYNC:
|
||||||
/**
|
return new NonSyncTimeRangeTracker();
|
||||||
* Default constructor.
|
case SYNC:
|
||||||
* Initializes TimeRange to be null
|
return new SyncTimeRangeTracker();
|
||||||
*/
|
default:
|
||||||
public TimeRangeTracker() {}
|
throw new UnsupportedOperationException("The type:" + type + " is unsupported");
|
||||||
|
}
|
||||||
/**
|
|
||||||
* Copy Constructor
|
|
||||||
* @param trt source TimeRangeTracker
|
|
||||||
*/
|
|
||||||
public TimeRangeTracker(final TimeRangeTracker trt) {
|
|
||||||
minimumTimestamp.set(trt.getMin());
|
|
||||||
maximumTimestamp.set(trt.getMax());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TimeRangeTracker(long minimumTimestamp, long maximumTimestamp) {
|
public static TimeRangeTracker create(Type type, TimeRangeTracker trt) {
|
||||||
this.minimumTimestamp.set(minimumTimestamp);
|
switch (type) {
|
||||||
this.maximumTimestamp.set(maximumTimestamp);
|
case NON_SYNC:
|
||||||
|
return new NonSyncTimeRangeTracker(trt);
|
||||||
|
case SYNC:
|
||||||
|
return new SyncTimeRangeTracker(trt);
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException("The type:" + type + " is unsupported");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static TimeRangeTracker create(Type type, long minimumTimestamp, long maximumTimestamp) {
|
||||||
|
switch (type) {
|
||||||
|
case NON_SYNC:
|
||||||
|
return new NonSyncTimeRangeTracker(minimumTimestamp, maximumTimestamp);
|
||||||
|
case SYNC:
|
||||||
|
return new SyncTimeRangeTracker(minimumTimestamp, maximumTimestamp);
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException("The type:" + type + " is unsupported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void setMax(long ts);
|
||||||
|
protected abstract void setMin(long ts);
|
||||||
|
protected abstract boolean compareAndSetMin(long expect, long update);
|
||||||
|
protected abstract boolean compareAndSetMax(long expect, long update);
|
||||||
/**
|
/**
|
||||||
* Update the current TimestampRange to include the timestamp from <code>cell</code>.
|
* Update the current TimestampRange to include the timestamp from <code>cell</code>.
|
||||||
* If the Key is of type DeleteColumn or DeleteFamily, it includes the
|
* If the Key is of type DeleteColumn or DeleteFamily, it includes the
|
||||||
|
@ -91,12 +113,12 @@ public class TimeRangeTracker implements Writable {
|
||||||
@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="MT_CORRECTNESS",
|
@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="MT_CORRECTNESS",
|
||||||
justification="Intentional")
|
justification="Intentional")
|
||||||
void includeTimestamp(final long timestamp) {
|
void includeTimestamp(final long timestamp) {
|
||||||
long initialMinTimestamp = this.minimumTimestamp.get();
|
long initialMinTimestamp = getMin();
|
||||||
if (timestamp < initialMinTimestamp) {
|
if (timestamp < initialMinTimestamp) {
|
||||||
long curMinTimestamp = initialMinTimestamp;
|
long curMinTimestamp = initialMinTimestamp;
|
||||||
while (timestamp < curMinTimestamp) {
|
while (timestamp < curMinTimestamp) {
|
||||||
if (!this.minimumTimestamp.compareAndSet(curMinTimestamp, timestamp)) {
|
if (!compareAndSetMin(curMinTimestamp, timestamp)) {
|
||||||
curMinTimestamp = this.minimumTimestamp.get();
|
curMinTimestamp = getMin();
|
||||||
} else {
|
} else {
|
||||||
// successfully set minimumTimestamp, break.
|
// successfully set minimumTimestamp, break.
|
||||||
break;
|
break;
|
||||||
|
@ -120,12 +142,12 @@ public class TimeRangeTracker implements Writable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long curMaxTimestamp = this.maximumTimestamp.get();
|
long curMaxTimestamp = getMax();
|
||||||
|
|
||||||
if (timestamp > curMaxTimestamp) {
|
if (timestamp > curMaxTimestamp) {
|
||||||
while (timestamp > curMaxTimestamp) {
|
while (timestamp > curMaxTimestamp) {
|
||||||
if (!this.maximumTimestamp.compareAndSet(curMaxTimestamp, timestamp)) {
|
if (!compareAndSetMax(curMaxTimestamp, timestamp)) {
|
||||||
curMaxTimestamp = this.maximumTimestamp.get();
|
curMaxTimestamp = getMax();
|
||||||
} else {
|
} else {
|
||||||
// successfully set maximumTimestamp, break
|
// successfully set maximumTimestamp, break
|
||||||
break;
|
break;
|
||||||
|
@ -140,48 +162,43 @@ public class TimeRangeTracker implements Writable {
|
||||||
* @return True if there is overlap, false otherwise
|
* @return True if there is overlap, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean includesTimeRange(final TimeRange tr) {
|
public boolean includesTimeRange(final TimeRange tr) {
|
||||||
return (this.minimumTimestamp.get() < tr.getMax() && this.maximumTimestamp.get() >= tr.getMin());
|
return (getMin() < tr.getMax() && getMax() >= tr.getMin());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the minimumTimestamp
|
* @return the minimumTimestamp
|
||||||
*/
|
*/
|
||||||
public long getMin() {
|
public abstract long getMin();
|
||||||
return minimumTimestamp.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the maximumTimestamp
|
* @return the maximumTimestamp
|
||||||
*/
|
*/
|
||||||
public long getMax() {
|
public abstract long getMax();
|
||||||
return maximumTimestamp.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void write(final DataOutput out) throws IOException {
|
public void write(final DataOutput out) throws IOException {
|
||||||
out.writeLong(minimumTimestamp.get());
|
out.writeLong(getMin());
|
||||||
out.writeLong(maximumTimestamp.get());
|
out.writeLong(getMax());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void readFields(final DataInput in) throws IOException {
|
public void readFields(final DataInput in) throws IOException {
|
||||||
|
setMin(in.readLong());
|
||||||
this.minimumTimestamp.set(in.readLong());
|
setMax(in.readLong());
|
||||||
this.maximumTimestamp.set(in.readLong());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[" + minimumTimestamp.get() + "," + maximumTimestamp.get() + "]";
|
return "[" + getMin() + "," + getMax() + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return An instance of TimeRangeTracker filled w/ the content of serialized
|
* @return An instance of NonSyncTimeRangeTracker filled w/ the content of serialized
|
||||||
* TimeRangeTracker in <code>timeRangeTrackerBytes</code>.
|
* NonSyncTimeRangeTracker in <code>timeRangeTrackerBytes</code>.
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public static TimeRangeTracker getTimeRangeTracker(final byte [] timeRangeTrackerBytes)
|
public static TimeRangeTracker getTimeRangeTracker(final byte [] timeRangeTrackerBytes)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if (timeRangeTrackerBytes == null) return null;
|
if (timeRangeTrackerBytes == null) return null;
|
||||||
TimeRangeTracker trt = new TimeRangeTracker();
|
TimeRangeTracker trt = TimeRangeTracker.create(Type.NON_SYNC);
|
||||||
Writables.copyWritable(timeRangeTrackerBytes, trt);
|
Writables.copyWritable(timeRangeTrackerBytes, trt);
|
||||||
return trt;
|
return trt;
|
||||||
}
|
}
|
||||||
|
@ -211,4 +228,110 @@ public class TimeRangeTracker implements Writable {
|
||||||
}
|
}
|
||||||
return new TimeRange(min, max);
|
return new TimeRange(min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class NonSyncTimeRangeTracker extends TimeRangeTracker {
|
||||||
|
private long minimumTimestamp = INITIAL_MIN_TIMESTAMP;
|
||||||
|
private long maximumTimestamp = INITIAL_MAX_TIMESTAMP;
|
||||||
|
|
||||||
|
NonSyncTimeRangeTracker() {
|
||||||
|
}
|
||||||
|
|
||||||
|
NonSyncTimeRangeTracker(final TimeRangeTracker trt) {
|
||||||
|
this.minimumTimestamp = trt.getMin();
|
||||||
|
this.maximumTimestamp = trt.getMax();
|
||||||
|
}
|
||||||
|
|
||||||
|
NonSyncTimeRangeTracker(long minimumTimestamp, long maximumTimestamp) {
|
||||||
|
this.minimumTimestamp = minimumTimestamp;
|
||||||
|
this.maximumTimestamp = maximumTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setMax(long ts) {
|
||||||
|
maximumTimestamp = ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setMin(long ts) {
|
||||||
|
minimumTimestamp = ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean compareAndSetMin(long expect, long update) {
|
||||||
|
if (minimumTimestamp != expect) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
minimumTimestamp = update;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean compareAndSetMax(long expect, long update) {
|
||||||
|
if (maximumTimestamp != expect) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
maximumTimestamp = update;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getMin() {
|
||||||
|
return minimumTimestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getMax() {
|
||||||
|
return maximumTimestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
//In order to estimate the heap size, this inner class need to be accessible to TestHeapSize.
|
||||||
|
public static class SyncTimeRangeTracker extends TimeRangeTracker {
|
||||||
|
private final AtomicLong minimumTimestamp = new AtomicLong(INITIAL_MIN_TIMESTAMP);
|
||||||
|
private final AtomicLong maximumTimestamp = new AtomicLong(INITIAL_MAX_TIMESTAMP);
|
||||||
|
|
||||||
|
private SyncTimeRangeTracker() {
|
||||||
|
}
|
||||||
|
|
||||||
|
SyncTimeRangeTracker(final TimeRangeTracker trt) {
|
||||||
|
this.minimumTimestamp.set(trt.getMin());
|
||||||
|
this.maximumTimestamp.set(trt.getMax());
|
||||||
|
}
|
||||||
|
|
||||||
|
SyncTimeRangeTracker(long minimumTimestamp, long maximumTimestamp) {
|
||||||
|
this.minimumTimestamp.set(minimumTimestamp);
|
||||||
|
this.maximumTimestamp.set(maximumTimestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setMax(long ts) {
|
||||||
|
maximumTimestamp.set(ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setMin(long ts) {
|
||||||
|
minimumTimestamp.set(ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean compareAndSetMin(long expect, long update) {
|
||||||
|
return minimumTimestamp.compareAndSet(expect, update);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean compareAndSetMax(long expect, long update) {
|
||||||
|
return maximumTimestamp.compareAndSet(expect, update);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getMin() {
|
||||||
|
return minimumTimestamp.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getMax() {
|
||||||
|
return maximumTimestamp.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,22 +19,9 @@
|
||||||
|
|
||||||
package org.apache.hadoop.hbase.io;
|
package org.apache.hadoop.hbase.io;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import static org.junit.Assert.assertEquals;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import static org.junit.Assert.assertTrue;
|
||||||
import org.apache.hadoop.hbase.KeyValue;
|
|
||||||
import org.apache.hadoop.hbase.client.Delete;
|
|
||||||
import org.apache.hadoop.hbase.client.Mutation;
|
|
||||||
import org.apache.hadoop.hbase.client.Put;
|
|
||||||
import org.apache.hadoop.hbase.io.hfile.BlockCacheKey;
|
|
||||||
import org.apache.hadoop.hbase.io.hfile.LruBlockCache;
|
|
||||||
import org.apache.hadoop.hbase.io.hfile.LruCachedBlock;
|
|
||||||
import org.apache.hadoop.hbase.regionserver.*;
|
|
||||||
import org.apache.hadoop.hbase.testclassification.IOTests;
|
|
||||||
import org.apache.hadoop.hbase.testclassification.SmallTests;
|
|
||||||
import org.apache.hadoop.hbase.util.ClassSize;
|
|
||||||
import org.junit.BeforeClass;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.experimental.categories.Category;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.management.ManagementFactory;
|
import java.lang.management.ManagementFactory;
|
||||||
import java.lang.management.RuntimeMXBean;
|
import java.lang.management.RuntimeMXBean;
|
||||||
|
@ -53,8 +40,35 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import org.apache.commons.logging.Log;
|
||||||
import static org.junit.Assert.assertTrue;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.apache.hadoop.hbase.KeyValue;
|
||||||
|
import org.apache.hadoop.hbase.client.Delete;
|
||||||
|
import org.apache.hadoop.hbase.client.Mutation;
|
||||||
|
import org.apache.hadoop.hbase.client.Put;
|
||||||
|
import org.apache.hadoop.hbase.io.hfile.BlockCacheKey;
|
||||||
|
import org.apache.hadoop.hbase.io.hfile.LruBlockCache;
|
||||||
|
import org.apache.hadoop.hbase.io.hfile.LruCachedBlock;
|
||||||
|
import org.apache.hadoop.hbase.regionserver.CSLMImmutableSegment;
|
||||||
|
import org.apache.hadoop.hbase.regionserver.CellArrayImmutableSegment;
|
||||||
|
import org.apache.hadoop.hbase.regionserver.CellArrayMap;
|
||||||
|
import org.apache.hadoop.hbase.regionserver.CellSet;
|
||||||
|
import org.apache.hadoop.hbase.regionserver.CompactingMemStore;
|
||||||
|
import org.apache.hadoop.hbase.regionserver.CompactionPipeline;
|
||||||
|
import org.apache.hadoop.hbase.regionserver.DefaultMemStore;
|
||||||
|
import org.apache.hadoop.hbase.regionserver.HRegion;
|
||||||
|
import org.apache.hadoop.hbase.regionserver.HStore;
|
||||||
|
import org.apache.hadoop.hbase.regionserver.ImmutableSegment;
|
||||||
|
import org.apache.hadoop.hbase.regionserver.MemStoreCompactor;
|
||||||
|
import org.apache.hadoop.hbase.regionserver.MutableSegment;
|
||||||
|
import org.apache.hadoop.hbase.regionserver.Segment;
|
||||||
|
import org.apache.hadoop.hbase.regionserver.TimeRangeTracker.SyncTimeRangeTracker;
|
||||||
|
import org.apache.hadoop.hbase.testclassification.IOTests;
|
||||||
|
import org.apache.hadoop.hbase.testclassification.SmallTests;
|
||||||
|
import org.apache.hadoop.hbase.util.ClassSize;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.experimental.categories.Category;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Testing the sizing that HeapSize offers and compares to the size given by
|
* Testing the sizing that HeapSize offers and compares to the size given by
|
||||||
|
@ -236,9 +250,9 @@ public class TestHeapSize {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TimeRangeTracker
|
// TimeRangeTracker
|
||||||
cl = TimeRangeTracker.class;
|
cl = SyncTimeRangeTracker.class;
|
||||||
expected = ClassSize.estimateBase(cl, false);
|
expected = ClassSize.estimateBase(cl, false);
|
||||||
actual = ClassSize.TIMERANGE_TRACKER;
|
actual = ClassSize.SYNC_TIMERANGE_TRACKER;
|
||||||
if (expected != actual) {
|
if (expected != actual) {
|
||||||
ClassSize.estimateBase(cl, true);
|
ClassSize.estimateBase(cl, true);
|
||||||
assertEquals(expected, actual);
|
assertEquals(expected, actual);
|
||||||
|
@ -347,13 +361,13 @@ public class TestHeapSize {
|
||||||
expected += 2 * ClassSize.estimateBase(AtomicLong.class, false);
|
expected += 2 * ClassSize.estimateBase(AtomicLong.class, false);
|
||||||
expected += ClassSize.estimateBase(AtomicReference.class, false);
|
expected += ClassSize.estimateBase(AtomicReference.class, false);
|
||||||
expected += ClassSize.estimateBase(CellSet.class, false);
|
expected += ClassSize.estimateBase(CellSet.class, false);
|
||||||
expected += ClassSize.estimateBase(TimeRangeTracker.class, false);
|
expected += ClassSize.estimateBase(SyncTimeRangeTracker.class, false);
|
||||||
if (expected != actual) {
|
if (expected != actual) {
|
||||||
ClassSize.estimateBase(cl, true);
|
ClassSize.estimateBase(cl, true);
|
||||||
ClassSize.estimateBase(AtomicLong.class, true);
|
ClassSize.estimateBase(AtomicLong.class, true);
|
||||||
ClassSize.estimateBase(AtomicReference.class, true);
|
ClassSize.estimateBase(AtomicReference.class, true);
|
||||||
ClassSize.estimateBase(CellSet.class, true);
|
ClassSize.estimateBase(CellSet.class, true);
|
||||||
ClassSize.estimateBase(TimeRangeTracker.class, true);
|
ClassSize.estimateBase(SyncTimeRangeTracker.class, true);
|
||||||
assertEquals(expected, actual);
|
assertEquals(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,7 +378,7 @@ public class TestHeapSize {
|
||||||
expected += 2 * ClassSize.estimateBase(AtomicLong.class, false);
|
expected += 2 * ClassSize.estimateBase(AtomicLong.class, false);
|
||||||
expected += ClassSize.estimateBase(AtomicReference.class, false);
|
expected += ClassSize.estimateBase(AtomicReference.class, false);
|
||||||
expected += ClassSize.estimateBase(CellSet.class, false);
|
expected += ClassSize.estimateBase(CellSet.class, false);
|
||||||
expected += ClassSize.estimateBase(TimeRangeTracker.class, false);
|
expected += ClassSize.estimateBase(SyncTimeRangeTracker.class, false);
|
||||||
expected += ClassSize.estimateBase(ConcurrentSkipListMap.class, false);
|
expected += ClassSize.estimateBase(ConcurrentSkipListMap.class, false);
|
||||||
if (expected != actual) {
|
if (expected != actual) {
|
||||||
ClassSize.estimateBase(cl, true);
|
ClassSize.estimateBase(cl, true);
|
||||||
|
@ -372,7 +386,7 @@ public class TestHeapSize {
|
||||||
ClassSize.estimateBase(AtomicLong.class, true);
|
ClassSize.estimateBase(AtomicLong.class, true);
|
||||||
ClassSize.estimateBase(AtomicReference.class, true);
|
ClassSize.estimateBase(AtomicReference.class, true);
|
||||||
ClassSize.estimateBase(CellSet.class, true);
|
ClassSize.estimateBase(CellSet.class, true);
|
||||||
ClassSize.estimateBase(TimeRangeTracker.class, true);
|
ClassSize.estimateBase(SyncTimeRangeTracker.class, true);
|
||||||
ClassSize.estimateBase(ConcurrentSkipListMap.class, true);
|
ClassSize.estimateBase(ConcurrentSkipListMap.class, true);
|
||||||
assertEquals(expected, actual);
|
assertEquals(expected, actual);
|
||||||
}
|
}
|
||||||
|
@ -384,7 +398,7 @@ public class TestHeapSize {
|
||||||
expected += 2 * ClassSize.estimateBase(AtomicLong.class, false);
|
expected += 2 * ClassSize.estimateBase(AtomicLong.class, false);
|
||||||
expected += ClassSize.estimateBase(AtomicReference.class, false);
|
expected += ClassSize.estimateBase(AtomicReference.class, false);
|
||||||
expected += ClassSize.estimateBase(CellSet.class, false);
|
expected += ClassSize.estimateBase(CellSet.class, false);
|
||||||
expected += ClassSize.estimateBase(TimeRangeTracker.class, false);
|
expected += ClassSize.estimateBase(SyncTimeRangeTracker.class, false);
|
||||||
expected += ClassSize.estimateBase(TimeRange.class, false);
|
expected += ClassSize.estimateBase(TimeRange.class, false);
|
||||||
if (expected != actual) {
|
if (expected != actual) {
|
||||||
ClassSize.estimateBase(cl, true);
|
ClassSize.estimateBase(cl, true);
|
||||||
|
@ -392,7 +406,7 @@ public class TestHeapSize {
|
||||||
ClassSize.estimateBase(AtomicLong.class, true);
|
ClassSize.estimateBase(AtomicLong.class, true);
|
||||||
ClassSize.estimateBase(AtomicReference.class, true);
|
ClassSize.estimateBase(AtomicReference.class, true);
|
||||||
ClassSize.estimateBase(CellSet.class, true);
|
ClassSize.estimateBase(CellSet.class, true);
|
||||||
ClassSize.estimateBase(TimeRangeTracker.class, true);
|
ClassSize.estimateBase(SyncTimeRangeTracker.class, true);
|
||||||
ClassSize.estimateBase(TimeRange.class, true);
|
ClassSize.estimateBase(TimeRange.class, true);
|
||||||
assertEquals(expected, actual);
|
assertEquals(expected, actual);
|
||||||
}
|
}
|
||||||
|
@ -403,7 +417,7 @@ public class TestHeapSize {
|
||||||
expected += 2 * ClassSize.estimateBase(AtomicLong.class, false);
|
expected += 2 * ClassSize.estimateBase(AtomicLong.class, false);
|
||||||
expected += ClassSize.estimateBase(AtomicReference.class, false);
|
expected += ClassSize.estimateBase(AtomicReference.class, false);
|
||||||
expected += ClassSize.estimateBase(CellSet.class, false);
|
expected += ClassSize.estimateBase(CellSet.class, false);
|
||||||
expected += ClassSize.estimateBase(TimeRangeTracker.class, false);
|
expected += ClassSize.estimateBase(SyncTimeRangeTracker.class, false);
|
||||||
expected += ClassSize.estimateBase(TimeRange.class, false);
|
expected += ClassSize.estimateBase(TimeRange.class, false);
|
||||||
expected += ClassSize.estimateBase(ConcurrentSkipListMap.class, false);
|
expected += ClassSize.estimateBase(ConcurrentSkipListMap.class, false);
|
||||||
if (expected != actual) {
|
if (expected != actual) {
|
||||||
|
@ -412,7 +426,7 @@ public class TestHeapSize {
|
||||||
ClassSize.estimateBase(AtomicLong.class, true);
|
ClassSize.estimateBase(AtomicLong.class, true);
|
||||||
ClassSize.estimateBase(AtomicReference.class, true);
|
ClassSize.estimateBase(AtomicReference.class, true);
|
||||||
ClassSize.estimateBase(CellSet.class, true);
|
ClassSize.estimateBase(CellSet.class, true);
|
||||||
ClassSize.estimateBase(TimeRangeTracker.class, true);
|
ClassSize.estimateBase(SyncTimeRangeTracker.class, true);
|
||||||
ClassSize.estimateBase(TimeRange.class, true);
|
ClassSize.estimateBase(TimeRange.class, true);
|
||||||
ClassSize.estimateBase(ConcurrentSkipListMap.class, true);
|
ClassSize.estimateBase(ConcurrentSkipListMap.class, true);
|
||||||
assertEquals(expected, actual);
|
assertEquals(expected, actual);
|
||||||
|
@ -423,7 +437,7 @@ public class TestHeapSize {
|
||||||
expected += 2 * ClassSize.estimateBase(AtomicLong.class, false);
|
expected += 2 * ClassSize.estimateBase(AtomicLong.class, false);
|
||||||
expected += ClassSize.estimateBase(AtomicReference.class, false);
|
expected += ClassSize.estimateBase(AtomicReference.class, false);
|
||||||
expected += ClassSize.estimateBase(CellSet.class, false);
|
expected += ClassSize.estimateBase(CellSet.class, false);
|
||||||
expected += ClassSize.estimateBase(TimeRangeTracker.class, false);
|
expected += ClassSize.estimateBase(SyncTimeRangeTracker.class, false);
|
||||||
expected += ClassSize.estimateBase(TimeRange.class, false);
|
expected += ClassSize.estimateBase(TimeRange.class, false);
|
||||||
expected += ClassSize.estimateBase(CellArrayMap.class, false);
|
expected += ClassSize.estimateBase(CellArrayMap.class, false);
|
||||||
if (expected != actual) {
|
if (expected != actual) {
|
||||||
|
@ -432,7 +446,7 @@ public class TestHeapSize {
|
||||||
ClassSize.estimateBase(AtomicLong.class, true);
|
ClassSize.estimateBase(AtomicLong.class, true);
|
||||||
ClassSize.estimateBase(AtomicReference.class, true);
|
ClassSize.estimateBase(AtomicReference.class, true);
|
||||||
ClassSize.estimateBase(CellSet.class, true);
|
ClassSize.estimateBase(CellSet.class, true);
|
||||||
ClassSize.estimateBase(TimeRangeTracker.class, true);
|
ClassSize.estimateBase(SyncTimeRangeTracker.class, true);
|
||||||
ClassSize.estimateBase(TimeRange.class, true);
|
ClassSize.estimateBase(TimeRange.class, true);
|
||||||
ClassSize.estimateBase(CellArrayMap.class, true);
|
ClassSize.estimateBase(CellArrayMap.class, true);
|
||||||
assertEquals(expected, actual);
|
assertEquals(expected, actual);
|
||||||
|
|
|
@ -49,7 +49,7 @@ public class AbstractTestDateTieredCompactionPolicy extends TestCompactionPolicy
|
||||||
for (int i = 0; i < sizes.length; i++) {
|
for (int i = 0; i < sizes.length; i++) {
|
||||||
MockHStoreFile msf =
|
MockHStoreFile msf =
|
||||||
new MockHStoreFile(TEST_UTIL, TEST_FILE, sizes[i], ageInDisk.get(i), false, i);
|
new MockHStoreFile(TEST_UTIL, TEST_FILE, sizes[i], ageInDisk.get(i), false, i);
|
||||||
msf.setTimeRangeTracker(new TimeRangeTracker(minTimestamps[i], maxTimestamps[i]));
|
msf.setTimeRangeTracker(TimeRangeTracker.create(TimeRangeTracker.Type.SYNC, minTimestamps[i], maxTimestamps[i]));
|
||||||
ret.add(msf);
|
ret.add(msf);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -168,7 +168,7 @@ public class TestDefaultCompactSelection extends TestCompactionPolicy {
|
||||||
for (HStoreFile file : candidates) {
|
for (HStoreFile file : candidates) {
|
||||||
if (file instanceof MockHStoreFile) {
|
if (file instanceof MockHStoreFile) {
|
||||||
MockHStoreFile mockFile = (MockHStoreFile) file;
|
MockHStoreFile mockFile = (MockHStoreFile) file;
|
||||||
mockFile.setTimeRangeTracker(new TimeRangeTracker(-1, -1));
|
mockFile.setTimeRangeTracker(TimeRangeTracker.create(TimeRangeTracker.Type.SYNC, -1, -1));
|
||||||
mockFile.setEntries(0);
|
mockFile.setEntries(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.hadoop.hbase.regionserver;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.hadoop.hbase.io.TimeRange;
|
||||||
|
import org.apache.hadoop.hbase.testclassification.RegionServerTests;
|
||||||
|
import org.apache.hadoop.hbase.testclassification.SmallTests;
|
||||||
|
import org.apache.hadoop.hbase.util.Writables;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.experimental.categories.Category;
|
||||||
|
|
||||||
|
@Category({RegionServerTests.class, SmallTests.class})
|
||||||
|
public class TestSimpleTimeRangeTracker {
|
||||||
|
|
||||||
|
protected TimeRangeTracker getTimeRangeTracker() {
|
||||||
|
return TimeRangeTracker.create(TimeRangeTracker.Type.NON_SYNC);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected TimeRangeTracker getTimeRangeTracker(long min, long max) {
|
||||||
|
return TimeRangeTracker.create(TimeRangeTracker.Type.NON_SYNC, min, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExtreme() {
|
||||||
|
TimeRange tr = new TimeRange();
|
||||||
|
assertTrue(tr.includesTimeRange(new TimeRange()));
|
||||||
|
TimeRangeTracker trt = getTimeRangeTracker();
|
||||||
|
assertFalse(trt.includesTimeRange(new TimeRange()));
|
||||||
|
trt.includeTimestamp(1);
|
||||||
|
trt.includeTimestamp(10);
|
||||||
|
assertTrue(trt.includesTimeRange(new TimeRange()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTimeRangeInitialized() {
|
||||||
|
TimeRangeTracker src = getTimeRangeTracker();
|
||||||
|
TimeRange tr = new TimeRange(System.currentTimeMillis());
|
||||||
|
assertFalse(src.includesTimeRange(tr));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTimeRangeTrackerNullIsSameAsTimeRangeNull() throws IOException {
|
||||||
|
TimeRangeTracker src = getTimeRangeTracker(1, 2);
|
||||||
|
byte [] bytes = Writables.getBytes(src);
|
||||||
|
TimeRange tgt = TimeRangeTracker.getTimeRange(bytes);
|
||||||
|
assertEquals(src.getMin(), tgt.getMin());
|
||||||
|
assertEquals(src.getMax(), tgt.getMax());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSerialization() throws IOException {
|
||||||
|
TimeRangeTracker src = getTimeRangeTracker(1, 2);
|
||||||
|
TimeRangeTracker tgt = getTimeRangeTracker();
|
||||||
|
Writables.copyWritable(src, tgt);
|
||||||
|
assertEquals(src.getMin(), tgt.getMin());
|
||||||
|
assertEquals(src.getMax(), tgt.getMax());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAlwaysDecrementingSetsMaximum() {
|
||||||
|
TimeRangeTracker trr = getTimeRangeTracker();
|
||||||
|
trr.includeTimestamp(3);
|
||||||
|
trr.includeTimestamp(2);
|
||||||
|
trr.includeTimestamp(1);
|
||||||
|
assertTrue(trr.getMin() != TimeRangeTracker.INITIAL_MIN_TIMESTAMP);
|
||||||
|
assertTrue(trr.getMax() != -1 /*The initial max value*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimpleInRange() {
|
||||||
|
TimeRangeTracker trr = getTimeRangeTracker();
|
||||||
|
trr.includeTimestamp(0);
|
||||||
|
trr.includeTimestamp(2);
|
||||||
|
assertTrue(trr.includesTimeRange(new TimeRange(1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRangeConstruction() throws IOException {
|
||||||
|
TimeRange defaultRange = new TimeRange();
|
||||||
|
assertEquals(0L, defaultRange.getMin());
|
||||||
|
assertEquals(Long.MAX_VALUE, defaultRange.getMax());
|
||||||
|
assertTrue(defaultRange.isAllTime());
|
||||||
|
|
||||||
|
TimeRange oneArgRange = new TimeRange(0L);
|
||||||
|
assertEquals(0L, oneArgRange.getMin());
|
||||||
|
assertEquals(Long.MAX_VALUE, oneArgRange.getMax());
|
||||||
|
assertTrue(oneArgRange.isAllTime());
|
||||||
|
|
||||||
|
TimeRange oneArgRange2 = new TimeRange(1);
|
||||||
|
assertEquals(1, oneArgRange2.getMin());
|
||||||
|
assertEquals(Long.MAX_VALUE, oneArgRange2.getMax());
|
||||||
|
assertFalse(oneArgRange2.isAllTime());
|
||||||
|
|
||||||
|
TimeRange twoArgRange = new TimeRange(0L, Long.MAX_VALUE);
|
||||||
|
assertEquals(0L, twoArgRange.getMin());
|
||||||
|
assertEquals(Long.MAX_VALUE, twoArgRange.getMax());
|
||||||
|
assertTrue(twoArgRange.isAllTime());
|
||||||
|
|
||||||
|
TimeRange twoArgRange2 = new TimeRange(0L, Long.MAX_VALUE - 1);
|
||||||
|
assertEquals(0L, twoArgRange2.getMin());
|
||||||
|
assertEquals(Long.MAX_VALUE - 1, twoArgRange2.getMax());
|
||||||
|
assertFalse(twoArgRange2.isAllTime());
|
||||||
|
|
||||||
|
TimeRange twoArgRange3 = new TimeRange(1, Long.MAX_VALUE);
|
||||||
|
assertEquals(1, twoArgRange3.getMin());
|
||||||
|
assertEquals(Long.MAX_VALUE, twoArgRange3.getMax());
|
||||||
|
assertFalse(twoArgRange3.isAllTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -17,76 +17,27 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hadoop.hbase.regionserver;
|
package org.apache.hadoop.hbase.regionserver;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.apache.hadoop.hbase.io.TimeRange;
|
|
||||||
import org.apache.hadoop.hbase.testclassification.SmallTests;
|
|
||||||
import org.apache.hadoop.hbase.util.Writables;
|
|
||||||
import org.apache.hadoop.hbase.testclassification.RegionServerTests;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.experimental.categories.Category;
|
|
||||||
|
|
||||||
import java.util.concurrent.ThreadLocalRandom;
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
|
import org.apache.hadoop.hbase.testclassification.RegionServerTests;
|
||||||
|
import org.apache.hadoop.hbase.testclassification.SmallTests;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.experimental.categories.Category;
|
||||||
|
|
||||||
@Category({RegionServerTests.class, SmallTests.class})
|
@Category({RegionServerTests.class, SmallTests.class})
|
||||||
public class TestTimeRangeTracker {
|
public class TestSyncTimeRangeTracker extends TestSimpleTimeRangeTracker {
|
||||||
|
|
||||||
private static final int NUM_KEYS = 10000000;
|
private static final int NUM_KEYS = 10000000;
|
||||||
|
private static final int NUM_OF_THREADS = 20;
|
||||||
|
|
||||||
@Test
|
protected TimeRangeTracker getTimeRangeTracker() {
|
||||||
public void testExtreme() {
|
return TimeRangeTracker.create(TimeRangeTracker.Type.SYNC);
|
||||||
TimeRange tr = new TimeRange();
|
|
||||||
assertTrue(tr.includesTimeRange(new TimeRange()));
|
|
||||||
TimeRangeTracker trt = new TimeRangeTracker();
|
|
||||||
assertFalse(trt.includesTimeRange(new TimeRange()));
|
|
||||||
trt.includeTimestamp(1);
|
|
||||||
trt.includeTimestamp(10);
|
|
||||||
assertTrue(trt.includesTimeRange(new TimeRange()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
protected TimeRangeTracker getTimeRangeTracker(long min, long max) {
|
||||||
public void testTimeRangeInitialized() {
|
return TimeRangeTracker.create(TimeRangeTracker.Type.SYNC, min, max);
|
||||||
TimeRangeTracker src = new TimeRangeTracker();
|
|
||||||
TimeRange tr = new TimeRange(System.currentTimeMillis());
|
|
||||||
assertFalse(src.includesTimeRange(tr));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testTimeRangeTrackerNullIsSameAsTimeRangeNull() throws IOException {
|
|
||||||
TimeRangeTracker src = new TimeRangeTracker(1, 2);
|
|
||||||
byte [] bytes = Writables.getBytes(src);
|
|
||||||
TimeRange tgt = TimeRangeTracker.getTimeRange(bytes);
|
|
||||||
assertEquals(src.getMin(), tgt.getMin());
|
|
||||||
assertEquals(src.getMax(), tgt.getMax());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSerialization() throws IOException {
|
|
||||||
TimeRangeTracker src = new TimeRangeTracker(1, 2);
|
|
||||||
TimeRangeTracker tgt = new TimeRangeTracker();
|
|
||||||
Writables.copyWritable(src, tgt);
|
|
||||||
assertEquals(src.getMin(), tgt.getMin());
|
|
||||||
assertEquals(src.getMax(), tgt.getMax());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAlwaysDecrementingSetsMaximum() {
|
|
||||||
TimeRangeTracker trr = new TimeRangeTracker();
|
|
||||||
trr.includeTimestamp(3);
|
|
||||||
trr.includeTimestamp(2);
|
|
||||||
trr.includeTimestamp(1);
|
|
||||||
assertTrue(trr.getMin() != TimeRangeTracker.INITIAL_MIN_TIMESTAMP);
|
|
||||||
assertTrue(trr.getMax() != -1 /*The initial max value*/);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSimpleInRange() {
|
|
||||||
TimeRangeTracker trr = new TimeRangeTracker();
|
|
||||||
trr.includeTimestamp(0);
|
|
||||||
trr.includeTimestamp(2);
|
|
||||||
assertTrue(trr.includesTimeRange(new TimeRange(1)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,7 +48,7 @@ public class TestTimeRangeTracker {
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testArriveAtRightAnswer() throws InterruptedException {
|
public void testArriveAtRightAnswer() throws InterruptedException {
|
||||||
final TimeRangeTracker trr = new TimeRangeTracker();
|
final TimeRangeTracker trr = getTimeRangeTracker();
|
||||||
final int threadCount = 10;
|
final int threadCount = 10;
|
||||||
final int calls = 1000 * 1000;
|
final int calls = 1000 * 1000;
|
||||||
Thread [] threads = new Thread[threadCount];
|
Thread [] threads = new Thread[threadCount];
|
||||||
|
@ -126,41 +77,6 @@ public class TestTimeRangeTracker {
|
||||||
assertTrue(trr.getMin() == 0);
|
assertTrue(trr.getMin() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRangeConstruction() throws IOException {
|
|
||||||
TimeRange defaultRange = new TimeRange();
|
|
||||||
assertEquals(0L, defaultRange.getMin());
|
|
||||||
assertEquals(Long.MAX_VALUE, defaultRange.getMax());
|
|
||||||
assertTrue(defaultRange.isAllTime());
|
|
||||||
|
|
||||||
TimeRange oneArgRange = new TimeRange(0L);
|
|
||||||
assertEquals(0L, oneArgRange.getMin());
|
|
||||||
assertEquals(Long.MAX_VALUE, oneArgRange.getMax());
|
|
||||||
assertTrue(oneArgRange.isAllTime());
|
|
||||||
|
|
||||||
TimeRange oneArgRange2 = new TimeRange(1);
|
|
||||||
assertEquals(1, oneArgRange2.getMin());
|
|
||||||
assertEquals(Long.MAX_VALUE, oneArgRange2.getMax());
|
|
||||||
assertFalse(oneArgRange2.isAllTime());
|
|
||||||
|
|
||||||
TimeRange twoArgRange = new TimeRange(0L, Long.MAX_VALUE);
|
|
||||||
assertEquals(0L, twoArgRange.getMin());
|
|
||||||
assertEquals(Long.MAX_VALUE, twoArgRange.getMax());
|
|
||||||
assertTrue(twoArgRange.isAllTime());
|
|
||||||
|
|
||||||
TimeRange twoArgRange2 = new TimeRange(0L, Long.MAX_VALUE - 1);
|
|
||||||
assertEquals(0L, twoArgRange2.getMin());
|
|
||||||
assertEquals(Long.MAX_VALUE - 1, twoArgRange2.getMax());
|
|
||||||
assertFalse(twoArgRange2.isAllTime());
|
|
||||||
|
|
||||||
TimeRange twoArgRange3 = new TimeRange(1, Long.MAX_VALUE);
|
|
||||||
assertEquals(1, twoArgRange3.getMin());
|
|
||||||
assertEquals(Long.MAX_VALUE, twoArgRange3.getMax());
|
|
||||||
assertFalse(twoArgRange3.isAllTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
final static int NUM_OF_THREADS = 20;
|
|
||||||
|
|
||||||
class RandomTestData {
|
class RandomTestData {
|
||||||
private long[] keys = new long[NUM_KEYS];
|
private long[] keys = new long[NUM_KEYS];
|
||||||
private long min = Long.MAX_VALUE;
|
private long min = Long.MAX_VALUE;
|
||||||
|
@ -226,7 +142,7 @@ public class TestTimeRangeTracker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeRangeTracker trt = new TimeRangeTracker();
|
TimeRangeTracker trt = TimeRangeTracker.create(TimeRangeTracker.Type.SYNC);
|
||||||
|
|
||||||
Thread[] t = new Thread[NUM_OF_THREADS];
|
Thread[] t = new Thread[NUM_OF_THREADS];
|
||||||
for (int i = 0; i < NUM_OF_THREADS; i++) {
|
for (int i = 0; i < NUM_OF_THREADS; i++) {
|
||||||
|
@ -245,32 +161,4 @@ public class TestTimeRangeTracker {
|
||||||
assertTrue(min == trt.getMin());
|
assertTrue(min == trt.getMin());
|
||||||
assertTrue(max == trt.getMax());
|
assertTrue(max == trt.getMax());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Bit of code to test concurrent access on this class.
|
|
||||||
* @param args
|
|
||||||
* @throws InterruptedException
|
|
||||||
*/
|
|
||||||
public static void main(String[] args) throws InterruptedException {
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
final TimeRangeTracker trr = new TimeRangeTracker();
|
|
||||||
final int threadCount = 5;
|
|
||||||
final int calls = 1024 * 1024 * 128;
|
|
||||||
Thread [] threads = new Thread[threadCount];
|
|
||||||
for (int i = 0; i < threads.length; i++) {
|
|
||||||
Thread t = new Thread("" + i) {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
for (int i = 0; i < calls; i++) trr.includeTimestamp(i);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
t.start();
|
|
||||||
threads[i] = t;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < threads.length; i++) {
|
|
||||||
threads[i].join();
|
|
||||||
}
|
|
||||||
System.out.println(trr.getMin() + " " + trr.getMax() + " " +
|
|
||||||
(System.currentTimeMillis() - start));
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue