1) Make TimelineEntry in VersionedIntervalTimeline a static class with its own generic parameters to hopefully make OpenJDK happier.

This commit is contained in:
Eric Tschetter 2012-11-02 11:35:23 -05:00
parent f07b15db1f
commit 63b2f502ac
2 changed files with 52 additions and 42 deletions

View File

@ -61,13 +61,13 @@ public class VersionedIntervalTimeline<VersionType, ObjectType>
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
final NavigableMap<Interval, TimelineEntry> completePartitionsTimeline = new TreeMap<Interval, TimelineEntry>(
final NavigableMap<Interval, TimelineEntry<VersionType, ObjectType>> completePartitionsTimeline = Maps.newTreeMap(
Comparators.intervalsByStartThenEnd()
);
final NavigableMap<Interval, TimelineEntry> incompletePartitionsTimeline = new TreeMap<Interval, TimelineEntry>(
final NavigableMap<Interval, TimelineEntry<VersionType, ObjectType>> incompletePartitionsTimeline = Maps.newTreeMap(
Comparators.intervalsByStartThenEnd()
);
private final Map<Interval, TreeMap<VersionType, TimelineEntry>> allTimelineEntries = Maps.newHashMap();
private final Map<Interval, TreeMap<VersionType, TimelineEntry<VersionType, ObjectType>>> allTimelineEntries = Maps.newHashMap();
private final Comparator<? super VersionType> versionComparator;
@ -83,19 +83,23 @@ public class VersionedIntervalTimeline<VersionType, ObjectType>
try {
lock.writeLock().lock();
Map<VersionType, TimelineEntry> exists = allTimelineEntries.get(interval);
TimelineEntry entry = null;
Map<VersionType, TimelineEntry<VersionType, ObjectType>> exists = allTimelineEntries.get(interval);
TimelineEntry<VersionType, ObjectType> entry = null;
if (exists == null) {
entry = new TimelineEntry(interval, version, new PartitionHolder<ObjectType>(object));
TreeMap<VersionType, TimelineEntry> versionEntry = Maps.newTreeMap(versionComparator);
entry = new TimelineEntry<VersionType, ObjectType>(interval, version, new PartitionHolder<ObjectType>(object));
TreeMap<VersionType, TimelineEntry<VersionType, ObjectType>> versionEntry = Maps.newTreeMap(versionComparator);
versionEntry.put(version, entry);
allTimelineEntries.put(interval, versionEntry);
} else {
entry = exists.get(version);
if (entry == null) {
entry = new TimelineEntry(interval, version, new PartitionHolder<ObjectType>(object));
entry = new TimelineEntry<VersionType, ObjectType>(
interval,
version,
new PartitionHolder<ObjectType>(object)
);
exists.put(version, entry);
} else {
PartitionHolder<ObjectType> partitionHolder = entry.getPartitionHolder();
@ -119,12 +123,12 @@ public class VersionedIntervalTimeline<VersionType, ObjectType>
try {
lock.writeLock().lock();
Map<VersionType, TimelineEntry> versionEntries = allTimelineEntries.get(interval);
Map<VersionType, TimelineEntry<VersionType, ObjectType>> versionEntries = allTimelineEntries.get(interval);
if (versionEntries == null) {
return null;
}
TimelineEntry entry = versionEntries.get(version);
TimelineEntry<VersionType, ObjectType> entry = versionEntries.get(version);
if (entry == null) {
return null;
}
@ -152,7 +156,7 @@ public class VersionedIntervalTimeline<VersionType, ObjectType>
{
try {
lock.readLock().lock();
for (Map.Entry<Interval, TreeMap<VersionType, TimelineEntry>> entry : allTimelineEntries.entrySet()) {
for (Map.Entry<Interval, TreeMap<VersionType, TimelineEntry<VersionType, ObjectType>>> entry : allTimelineEntries.entrySet()) {
if (entry.getKey().equals(interval) || entry.getKey().contains(interval)) {
TimelineEntry foundEntry = entry.getValue().get(version);
if (foundEntry != null) {
@ -197,13 +201,14 @@ public class VersionedIntervalTimeline<VersionType, ObjectType>
List<TimelineObjectHolder<VersionType, ObjectType>> retVal = new ArrayList<TimelineObjectHolder<VersionType, ObjectType>>();
Map<Interval, Map<VersionType, TimelineEntry>> overShadowed = Maps.newHashMap();
for (Map.Entry<Interval, TreeMap<VersionType, TimelineEntry>> versionEntry : allTimelineEntries.entrySet()) {
for (Map.Entry<Interval, TreeMap<VersionType, TimelineEntry<VersionType, ObjectType>>> versionEntry : allTimelineEntries
.entrySet()) {
Map<VersionType, TimelineEntry> versionCopy = Maps.newHashMap();
versionCopy.putAll(versionEntry.getValue());
overShadowed.put(versionEntry.getKey(), versionCopy);
}
for (Map.Entry<Interval, TimelineEntry> entry : completePartitionsTimeline.entrySet()) {
for (Map.Entry<Interval, TimelineEntry<VersionType, ObjectType>> entry : completePartitionsTimeline.entrySet()) {
Map<VersionType, TimelineEntry> versionEntry = overShadowed.get(entry.getValue().getTrueInterval());
if (versionEntry != null) {
versionEntry.remove(entry.getValue().getVersion());
@ -213,7 +218,7 @@ public class VersionedIntervalTimeline<VersionType, ObjectType>
}
}
for (Map.Entry<Interval, TimelineEntry> entry : incompletePartitionsTimeline.entrySet()) {
for (Map.Entry<Interval, TimelineEntry<VersionType, ObjectType>> entry : incompletePartitionsTimeline.entrySet()) {
Map<VersionType, TimelineEntry> versionEntry = overShadowed.get(entry.getValue().getTrueInterval());
if (versionEntry != null) {
versionEntry.remove(entry.getValue().getVersion());
@ -225,7 +230,7 @@ public class VersionedIntervalTimeline<VersionType, ObjectType>
for (Map.Entry<Interval, Map<VersionType, TimelineEntry>> versionEntry : overShadowed.entrySet()) {
for (Map.Entry<VersionType, TimelineEntry> entry : versionEntry.getValue().entrySet()) {
TimelineEntry object = entry.getValue();
TimelineEntry<VersionType, ObjectType> object = entry.getValue();
retVal.add(
new TimelineObjectHolder<VersionType, ObjectType>(
object.getTrueInterval(),
@ -244,12 +249,12 @@ public class VersionedIntervalTimeline<VersionType, ObjectType>
}
private void add(
NavigableMap<Interval, TimelineEntry> timeline,
NavigableMap<Interval, TimelineEntry<VersionType, ObjectType>> timeline,
Interval interval,
TimelineEntry entry
TimelineEntry<VersionType, ObjectType> entry
)
{
TimelineEntry existsInTimeline = timeline.get(interval);
TimelineEntry<VersionType, ObjectType> existsInTimeline = timeline.get(interval);
if (existsInTimeline != null) {
int compare = versionComparator.compare(entry.getVersion(), existsInTimeline.getVersion());
@ -279,9 +284,9 @@ public class VersionedIntervalTimeline<VersionType, ObjectType>
}
private boolean addAtKey(
NavigableMap<Interval, TimelineEntry> timeline,
NavigableMap<Interval, TimelineEntry<VersionType, ObjectType>> timeline,
Interval key,
TimelineEntry entry
TimelineEntry<VersionType, ObjectType> entry
)
{
boolean retVal = false;
@ -315,7 +320,7 @@ public class VersionedIntervalTimeline<VersionType, ObjectType>
}
}
} else if (versionCompare > 0) {
TimelineEntry oldEntry = timeline.remove(currKey);
TimelineEntry<VersionType, ObjectType> oldEntry = timeline.remove(currKey);
if (currKey.contains(entryInterval)) {
addIntervalToTimeline(new Interval(currKey.getStart(), entryInterval.getStart()), oldEntry, timeline);
@ -355,8 +360,8 @@ public class VersionedIntervalTimeline<VersionType, ObjectType>
private void addIntervalToTimeline(
Interval interval,
TimelineEntry entry,
NavigableMap<Interval, TimelineEntry> timeline
TimelineEntry<VersionType, ObjectType> entry,
NavigableMap<Interval, TimelineEntry<VersionType, ObjectType>> timeline
)
{
if (interval != null && interval.toDurationMillis() > 0) {
@ -365,9 +370,9 @@ public class VersionedIntervalTimeline<VersionType, ObjectType>
}
private void remove(
NavigableMap<Interval, TimelineEntry> timeline,
NavigableMap<Interval, TimelineEntry<VersionType, ObjectType>> timeline,
Interval interval,
TimelineEntry entry,
TimelineEntry<VersionType, ObjectType> entry,
boolean incompleteOk
)
{
@ -375,9 +380,9 @@ public class VersionedIntervalTimeline<VersionType, ObjectType>
TimelineEntry removed = timeline.get(interval);
if (removed == null) {
Iterator<Map.Entry<Interval, TimelineEntry>> iter = timeline.entrySet().iterator();
Iterator<Map.Entry<Interval, TimelineEntry<VersionType, ObjectType>>> iter = timeline.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<Interval, TimelineEntry> timelineEntry = iter.next();
Map.Entry<Interval, TimelineEntry<VersionType, ObjectType>> timelineEntry = iter.next();
if (timelineEntry.getValue() == entry) {
intervalsToRemove.add(timelineEntry.getKey());
}
@ -392,14 +397,15 @@ public class VersionedIntervalTimeline<VersionType, ObjectType>
}
private void remove(
NavigableMap<Interval, TimelineEntry> timeline,
NavigableMap<Interval, TimelineEntry<VersionType, ObjectType>> timeline,
Interval interval,
boolean incompleteOk
)
{
timeline.remove(interval);
for (Map.Entry<Interval, TreeMap<VersionType, TimelineEntry>> versionEntry : allTimelineEntries.entrySet()) {
for (Map.Entry<Interval, TreeMap<VersionType, TimelineEntry<VersionType, ObjectType>>> versionEntry : allTimelineEntries
.entrySet()) {
if (versionEntry.getKey().overlap(interval) != null) {
TimelineEntry timelineEntry = versionEntry.getValue().lastEntry().getValue();
if (timelineEntry.getPartitionHolder().isComplete() || incompleteOk) {
@ -412,20 +418,18 @@ public class VersionedIntervalTimeline<VersionType, ObjectType>
private List<TimelineObjectHolder<VersionType, ObjectType>> lookup(Interval interval, boolean incompleteOk)
{
List<TimelineObjectHolder<VersionType, ObjectType>> retVal = new ArrayList<TimelineObjectHolder<VersionType, ObjectType>>();
NavigableMap<Interval, TimelineEntry> timeline = (incompleteOk)
? incompletePartitionsTimeline
: completePartitionsTimeline;
NavigableMap<Interval, TimelineEntry<VersionType, ObjectType>> timeline = (incompleteOk)
? incompletePartitionsTimeline
: completePartitionsTimeline;
for (Map.Entry<Interval, TimelineEntry> entry : timeline.entrySet()) {
for (Map.Entry<Interval, TimelineEntry<VersionType, ObjectType>> entry : timeline.entrySet()) {
Interval timelineInterval = entry.getKey();
TimelineEntry val = entry.getValue();
TimelineEntry<VersionType, ObjectType> val = entry.getValue();
if (timelineInterval.overlaps(interval)) {
retVal.add(
new TimelineObjectHolder<VersionType, ObjectType>(
timelineInterval,
val.getVersion(),
val.getPartitionHolder()
timelineInterval, val.getVersion(), val.getPartitionHolder()
)
);
}
@ -463,30 +467,30 @@ public class VersionedIntervalTimeline<VersionType, ObjectType>
return retVal;
}
public class TimelineEntry
private static class TimelineEntry<VersionType, ObjectType>
{
private final Interval trueInterval;
private final VersionType version;
private final PartitionHolder<ObjectType> partitionHolder;
public TimelineEntry(Interval trueInterval, VersionType version, PartitionHolder<ObjectType> partitionHolder)
private TimelineEntry(Interval trueInterval, VersionType version, PartitionHolder<ObjectType> partitionHolder)
{
this.trueInterval = trueInterval;
this.version = version;
this.partitionHolder = partitionHolder;
}
public Interval getTrueInterval()
private Interval getTrueInterval()
{
return trueInterval;
}
public VersionType getVersion()
private VersionType getVersion()
{
return version;
}
public PartitionHolder<ObjectType> getPartitionHolder()
private PartitionHolder<ObjectType> getPartitionHolder()
{
return partitionHolder;
}

View File

@ -21,6 +21,7 @@ package com.metamx.druid;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Ordering;
import com.metamx.common.ISE;
import com.metamx.common.Pair;
import com.metamx.druid.partition.ImmutablePartitionHolder;
import com.metamx.druid.partition.IntegerPartitionChunk;
@ -28,6 +29,7 @@ import com.metamx.druid.partition.PartitionChunk;
import com.metamx.druid.partition.PartitionHolder;
import com.metamx.druid.partition.SingleElementPartitionChunk;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Days;
import org.joda.time.Hours;
import org.joda.time.Interval;
@ -48,6 +50,10 @@ public class VersionedIntervalTimelineTest
@Before
public void setUp() throws Exception
{
if (! "UTC".equals(DateTimeZone.getDefault().getID())) {
throw new ISE("Tests assume default timezone of UTC, please set -Duser.timezone=UTC");
}
timeline = makeStringIntegerTimeline();
add("2011-04-01/2011-04-03", "1", 2);