-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Avoid expensive findEntry call in segment metadata query #10892
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
452fdd0
4e6d143
aef9f17
386fed6
b2efed2
659c1de
675a958
cfea19f
ec121c2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,7 +20,6 @@ | |
| package org.apache.druid.timeline; | ||
|
|
||
| import com.google.common.annotations.VisibleForTesting; | ||
| import com.google.common.base.Function; | ||
| import com.google.common.base.Preconditions; | ||
| import com.google.common.collect.FluentIterable; | ||
| import com.google.common.collect.Iterators; | ||
|
|
@@ -117,10 +116,14 @@ public static void addSegments( | |
| ) | ||
| { | ||
| timeline.addAll( | ||
| Iterators.transform(segments, segment -> segment.getShardSpec().createChunk(segment)), | ||
| DataSegment::getInterval, | ||
| DataSegment::getVersion | ||
| ); | ||
| Iterators.transform( | ||
| segments, | ||
| segment -> new PartitionChunkEntry<>( | ||
| segment.getInterval(), | ||
| segment.getVersion(), | ||
| segment.getShardSpec().createChunk(segment) | ||
| ) | ||
| )); | ||
| } | ||
|
|
||
| public Map<Interval, TreeMap<VersionType, TimelineEntry>> getAllTimelineEntries() | ||
|
|
@@ -183,13 +186,11 @@ public Set<ObjectType> findNonOvershadowedObjectsInInterval(Interval interval, P | |
|
|
||
| public void add(final Interval interval, VersionType version, PartitionChunk<ObjectType> object) | ||
| { | ||
| addAll(Iterators.singletonIterator(object), o -> interval, o -> version); | ||
| addAll(Iterators.singletonIterator(new PartitionChunkEntry<>(interval, version, object))); | ||
| } | ||
|
|
||
| private void addAll( | ||
| final Iterator<PartitionChunk<ObjectType>> objects, | ||
| final Function<ObjectType, Interval> intervalFunction, | ||
| final Function<ObjectType, VersionType> versionFunction | ||
| public void addAll( | ||
| final Iterator<PartitionChunkEntry<VersionType, ObjectType>> objects | ||
| ) | ||
| { | ||
| lock.writeLock().lock(); | ||
|
|
@@ -198,9 +199,10 @@ private void addAll( | |
| final IdentityHashMap<TimelineEntry, Interval> allEntries = new IdentityHashMap<>(); | ||
|
|
||
| while (objects.hasNext()) { | ||
| PartitionChunk<ObjectType> object = objects.next(); | ||
| Interval interval = intervalFunction.apply(object.getObject()); | ||
| VersionType version = versionFunction.apply(object.getObject()); | ||
| PartitionChunkEntry<VersionType, ObjectType> chunkEntry = objects.next(); | ||
| PartitionChunk<ObjectType> object = chunkEntry.getChunk(); | ||
| Interval interval = chunkEntry.getInterval(); | ||
| VersionType version = chunkEntry.getVersion(); | ||
| Map<VersionType, TimelineEntry> exists = allTimelineEntries.get(interval); | ||
| TimelineEntry entry; | ||
|
|
||
|
|
@@ -284,15 +286,15 @@ public PartitionChunk<ObjectType> remove(Interval interval, VersionType version, | |
|
|
||
| @Override | ||
| @Nullable | ||
| public PartitionHolder<ObjectType> findEntry(Interval interval, VersionType version) | ||
| public PartitionChunk<ObjectType> findChunk(Interval interval, VersionType version, int partitionNum) | ||
| { | ||
| lock.readLock().lock(); | ||
| try { | ||
| for (Entry<Interval, TreeMap<VersionType, TimelineEntry>> entry : allTimelineEntries.entrySet()) { | ||
| if (entry.getKey().equals(interval) || entry.getKey().contains(interval)) { | ||
| TimelineEntry foundEntry = entry.getValue().get(version); | ||
| if (foundEntry != null) { | ||
| return foundEntry.getPartitionHolder().asImmutable(); | ||
| return foundEntry.getPartitionHolder().getChunk(partitionNum); | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -849,4 +851,41 @@ public int hashCode() | |
| return Objects.hash(trueInterval, version, partitionHolder); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Stores a {@link PartitionChunk} for a given interval and version. The | ||
| * interval corresponds to the {@link LogicalSegment#getInterval()} | ||
| */ | ||
| public static class PartitionChunkEntry<VersionType, ObjectType> | ||
| { | ||
| private final Interval interval; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add javadoc explaining what this interval is. There are two types of interval in timeline. See |
||
| private final VersionType version; | ||
| private final PartitionChunk<ObjectType> chunk; | ||
|
|
||
| public PartitionChunkEntry( | ||
| Interval interval, | ||
| VersionType version, | ||
| PartitionChunk<ObjectType> chunk | ||
| ) | ||
| { | ||
| this.interval = interval; | ||
| this.version = version; | ||
| this.chunk = chunk; | ||
| } | ||
|
|
||
| public Interval getInterval() | ||
| { | ||
| return interval; | ||
| } | ||
|
|
||
| public VersionType getVersion() | ||
| { | ||
| return version; | ||
| } | ||
|
|
||
| public PartitionChunk<ObjectType> getChunk() | ||
| { | ||
| return chunk; | ||
| } | ||
| } | ||
| } | ||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -98,6 +98,16 @@ static void assertValues( | |
| Assert.assertEquals(expected, actualSet); | ||
| } | ||
|
|
||
| static void assertSingleElementChunks( | ||
| PartitionChunk<OvershadowableInteger> expected, | ||
| PartitionChunk<OvershadowableInteger> actual | ||
| ) | ||
| { | ||
| SingleElementPartitionChunk<OvershadowableInteger> expectedSingle = (SingleElementPartitionChunk<OvershadowableInteger>) expected; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since it's unrelated to my change, I will leave this one for now as it is. Though I did mark |
||
| SingleElementPartitionChunk<OvershadowableInteger> actualSingle = (SingleElementPartitionChunk<OvershadowableInteger>) actual; | ||
| Assert.assertEquals(expectedSingle.getObject(), actualSingle.getObject()); | ||
| } | ||
|
|
||
| static VersionedIntervalTimeline<String, OvershadowableInteger> makeStringIntegerTimeline() | ||
| { | ||
| return new VersionedIntervalTimeline<>(Ordering.natural()); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the asImmutable method still needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like its not. will delete this method as well as the class ImmutablePartitionHolder.