From e662efa79fbdb9e0664982565d6b91c25765a903 Mon Sep 17 00:00:00 2001 From: John Wang Date: Thu, 26 May 2016 20:36:41 -0700 Subject: [PATCH] segment interface refactor for proposal 2965 (#2990) --- .../io/druid/segment/AbstractSegment.java | 33 +++++++++++++++++++ .../segment/IncrementalIndexSegment.java | 3 +- .../druid/segment/QueryableIndexSegment.java | 2 +- .../segment/ReferenceCountingSegment.java | 3 +- .../main/java/io/druid/segment/Segment.java | 19 +++++++++++ .../druid/query/MultiValuedDimensionTest.java | 11 ++++--- .../aggregation/AggregationTestHelper.java | 3 ++ .../segment/ReferenceCountingSegmentTest.java | 2 +- .../loading/CacheTestSegmentLoader.java | 5 ++- .../coordination/ServerManagerTest.java | 7 ++-- 10 files changed, 77 insertions(+), 11 deletions(-) create mode 100644 processing/src/main/java/io/druid/segment/AbstractSegment.java diff --git a/processing/src/main/java/io/druid/segment/AbstractSegment.java b/processing/src/main/java/io/druid/segment/AbstractSegment.java new file mode 100644 index 00000000000..c82f11ccf35 --- /dev/null +++ b/processing/src/main/java/io/druid/segment/AbstractSegment.java @@ -0,0 +1,33 @@ +/* + * Licensed to Metamarkets Group Inc. (Metamarkets) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. Metamarkets 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 io.druid.segment; + +public abstract class AbstractSegment implements Segment +{ + @Override + public T as(Class clazz) + { + if (clazz.equals(QueryableIndex.class)) { + return (T) asQueryableIndex(); + } else if (clazz.equals(StorageAdapter.class)) { + return (T) asStorageAdapter(); + } + return null; + } +} diff --git a/processing/src/main/java/io/druid/segment/IncrementalIndexSegment.java b/processing/src/main/java/io/druid/segment/IncrementalIndexSegment.java index 081645edb67..20575169fa0 100644 --- a/processing/src/main/java/io/druid/segment/IncrementalIndexSegment.java +++ b/processing/src/main/java/io/druid/segment/IncrementalIndexSegment.java @@ -21,13 +21,14 @@ package io.druid.segment; import io.druid.segment.incremental.IncrementalIndex; import io.druid.segment.incremental.IncrementalIndexStorageAdapter; + import org.joda.time.Interval; import java.io.IOException; /** */ -public class IncrementalIndexSegment implements Segment +public class IncrementalIndexSegment extends AbstractSegment { private final IncrementalIndex index; private final String segmentIdentifier; diff --git a/processing/src/main/java/io/druid/segment/QueryableIndexSegment.java b/processing/src/main/java/io/druid/segment/QueryableIndexSegment.java index c7eb0ff4e9b..d1259fa335f 100644 --- a/processing/src/main/java/io/druid/segment/QueryableIndexSegment.java +++ b/processing/src/main/java/io/druid/segment/QueryableIndexSegment.java @@ -25,7 +25,7 @@ import java.io.IOException; /** */ -public class QueryableIndexSegment implements Segment +public class QueryableIndexSegment extends AbstractSegment { private final QueryableIndex index; private final String identifier; diff --git a/processing/src/main/java/io/druid/segment/ReferenceCountingSegment.java b/processing/src/main/java/io/druid/segment/ReferenceCountingSegment.java index 062f06feb1a..9eabf277f0b 100644 --- a/processing/src/main/java/io/druid/segment/ReferenceCountingSegment.java +++ b/processing/src/main/java/io/druid/segment/ReferenceCountingSegment.java @@ -20,13 +20,14 @@ package io.druid.segment; import com.metamx.emitter.EmittingLogger; + import org.joda.time.Interval; import java.io.Closeable; import java.io.IOException; import java.util.concurrent.atomic.AtomicBoolean; -public class ReferenceCountingSegment implements Segment +public class ReferenceCountingSegment extends AbstractSegment { private static final EmittingLogger log = new EmittingLogger(ReferenceCountingSegment.class); diff --git a/processing/src/main/java/io/druid/segment/Segment.java b/processing/src/main/java/io/druid/segment/Segment.java index 64e6d8e2354..aef3dc86513 100644 --- a/processing/src/main/java/io/druid/segment/Segment.java +++ b/processing/src/main/java/io/druid/segment/Segment.java @@ -31,4 +31,23 @@ public interface Segment extends Closeable public Interval getDataInterval(); public QueryableIndex asQueryableIndex(); public StorageAdapter asStorageAdapter(); + + /** + * Request an implementation of a particular interface. + * + * If the passed-in interface is {@link QueryableIndex} or {@link StorageAdapter}, then this method behaves + * identically to {@link #asQueryableIndex()} or {@link #asStorageAdapter()}. Other interfaces are only + * expected to be requested by callers that have specific knowledge of extra features provided by specific + * segment types. For example, an extension might provide a custom Segment type that can offer both + * StorageAdapter and some new interface. That extension can also offer a Query that uses that new interface. + * + * Implementations which accept classes other than {@link QueryableIndex} or {@link StorageAdapter} are limited + * to using those classes within the extension. This means that one extension cannot rely on the `Segment.as` + * behavior of another extension. + * + * @param clazz desired interface + * @param desired interface + * @return instance of clazz, or null if the interface is not supported by this segment + */ + public T as(Class clazz); } diff --git a/processing/src/test/java/io/druid/query/MultiValuedDimensionTest.java b/processing/src/test/java/io/druid/query/MultiValuedDimensionTest.java index 37457271d9b..7387cf2c134 100644 --- a/processing/src/test/java/io/druid/query/MultiValuedDimensionTest.java +++ b/processing/src/test/java/io/druid/query/MultiValuedDimensionTest.java @@ -28,6 +28,7 @@ import com.google.common.collect.Maps; import com.google.common.io.Files; import com.metamx.common.guava.Sequence; import com.metamx.common.guava.Sequences; + import io.druid.data.input.Row; import io.druid.data.input.impl.CSVParseSpec; import io.druid.data.input.impl.DimensionsSpec; @@ -55,9 +56,11 @@ import io.druid.segment.IncrementalIndexSegment; import io.druid.segment.IndexSpec; import io.druid.segment.QueryableIndex; import io.druid.segment.QueryableIndexSegment; +import io.druid.segment.Segment; import io.druid.segment.TestHelper; import io.druid.segment.incremental.IncrementalIndex; import io.druid.segment.incremental.OnheapIncrementalIndex; + import org.apache.commons.io.FileUtils; import org.joda.time.DateTime; import org.junit.AfterClass; @@ -150,7 +153,7 @@ public class MultiValuedDimensionTest .build(); Sequence result = helper.runQueryOnSegmentsObjs( - ImmutableList.of( + ImmutableList.of( new QueryableIndexSegment("sid1", queryableIndex), new IncrementalIndexSegment(incrementalIndex, "sid2") ), @@ -170,7 +173,7 @@ public class MultiValuedDimensionTest TestHelper.assertExpectedObjects(expectedResults, Sequences.toList(result, new ArrayList()), ""); result = helper.runQueryOnSegmentsObjs( - ImmutableList.of( + ImmutableList.of( new QueryableIndexSegment("sid1", queryableIndex), new IncrementalIndexSegment(incrementalIndex, "sid2") ), @@ -201,7 +204,7 @@ public class MultiValuedDimensionTest .build(); Sequence result = helper.runQueryOnSegmentsObjs( - ImmutableList.of( + ImmutableList.of( new QueryableIndexSegment("sid1", queryableIndex), new IncrementalIndexSegment(incrementalIndex, "sid2") ), @@ -249,7 +252,7 @@ public class MultiValuedDimensionTest .build(); Sequence result = helper.runQueryOnSegmentsObjs( - ImmutableList.of( + ImmutableList.of( new QueryableIndexSegment("sid1", queryableIndex), new IncrementalIndexSegment(incrementalIndex, "sid2") ), diff --git a/processing/src/test/java/io/druid/query/aggregation/AggregationTestHelper.java b/processing/src/test/java/io/druid/query/aggregation/AggregationTestHelper.java index 3e62ac393c8..19b9b9c6f6d 100644 --- a/processing/src/test/java/io/druid/query/aggregation/AggregationTestHelper.java +++ b/processing/src/test/java/io/druid/query/aggregation/AggregationTestHelper.java @@ -41,6 +41,7 @@ import com.metamx.common.guava.Sequence; import com.metamx.common.guava.Sequences; import com.metamx.common.guava.Yielder; import com.metamx.common.guava.YieldingAccumulator; + import io.druid.collections.StupidPool; import io.druid.data.input.Row; import io.druid.data.input.impl.InputRowParser; @@ -63,6 +64,7 @@ import io.druid.query.groupby.GroupByQueryRunnerFactory; import io.druid.query.select.SelectQueryEngine; import io.druid.query.select.SelectQueryQueryToolChest; import io.druid.query.select.SelectQueryRunnerFactory; +import io.druid.segment.AbstractSegment; import io.druid.segment.IndexIO; import io.druid.segment.IndexMerger; import io.druid.segment.IndexSpec; @@ -72,6 +74,7 @@ import io.druid.segment.Segment; import io.druid.segment.column.ColumnConfig; import io.druid.segment.incremental.IncrementalIndex; import io.druid.segment.incremental.OnheapIncrementalIndex; + import org.apache.commons.io.IOUtils; import org.apache.commons.io.LineIterator; import org.junit.rules.TemporaryFolder; diff --git a/processing/src/test/java/io/druid/segment/ReferenceCountingSegmentTest.java b/processing/src/test/java/io/druid/segment/ReferenceCountingSegmentTest.java index 6a861ed865a..ac66b6c4c3d 100644 --- a/processing/src/test/java/io/druid/segment/ReferenceCountingSegmentTest.java +++ b/processing/src/test/java/io/druid/segment/ReferenceCountingSegmentTest.java @@ -43,7 +43,7 @@ public class ReferenceCountingSegmentTest public void setUp() throws Exception { segment = new ReferenceCountingSegment( - new Segment() + new AbstractSegment() { @Override public String getIdentifier() diff --git a/server/src/test/java/io/druid/segment/loading/CacheTestSegmentLoader.java b/server/src/test/java/io/druid/segment/loading/CacheTestSegmentLoader.java index 7b5137e7fb5..f6db238acc1 100644 --- a/server/src/test/java/io/druid/segment/loading/CacheTestSegmentLoader.java +++ b/server/src/test/java/io/druid/segment/loading/CacheTestSegmentLoader.java @@ -20,10 +20,13 @@ package io.druid.segment.loading; import com.metamx.common.MapUtils; + +import io.druid.segment.AbstractSegment; import io.druid.segment.QueryableIndex; import io.druid.segment.Segment; import io.druid.segment.StorageAdapter; import io.druid.timeline.DataSegment; + import org.joda.time.Interval; import java.io.File; @@ -49,7 +52,7 @@ public class CacheTestSegmentLoader implements SegmentLoader @Override public Segment getSegment(final DataSegment segment) throws SegmentLoadingException { - return new Segment() + return new AbstractSegment() { @Override public String getIdentifier() diff --git a/server/src/test/java/io/druid/server/coordination/ServerManagerTest.java b/server/src/test/java/io/druid/server/coordination/ServerManagerTest.java index a7c49295d28..b2b968b497c 100644 --- a/server/src/test/java/io/druid/server/coordination/ServerManagerTest.java +++ b/server/src/test/java/io/druid/server/coordination/ServerManagerTest.java @@ -37,10 +37,11 @@ import com.metamx.common.guava.YieldingAccumulator; import com.metamx.common.guava.YieldingSequenceBase; import com.metamx.emitter.EmittingLogger; import com.metamx.emitter.service.ServiceMetricEvent; + import io.druid.client.cache.CacheConfig; import io.druid.client.cache.LocalCacheProvider; -import io.druid.granularity.QueryGranularity; import io.druid.granularity.QueryGranularities; +import io.druid.granularity.QueryGranularity; import io.druid.jackson.DefaultObjectMapper; import io.druid.query.ConcatQueryRunner; import io.druid.query.Druids; @@ -54,6 +55,7 @@ import io.druid.query.Result; import io.druid.query.aggregation.MetricManipulationFn; import io.druid.query.search.SearchResultValue; import io.druid.query.search.search.SearchQuery; +import io.druid.segment.AbstractSegment; import io.druid.segment.IndexIO; import io.druid.segment.QueryableIndex; import io.druid.segment.ReferenceCountingSegment; @@ -64,6 +66,7 @@ import io.druid.segment.loading.SegmentLoadingException; import io.druid.server.metrics.NoopServiceEmitter; import io.druid.timeline.DataSegment; import io.druid.timeline.partition.NoneShardSpec; + import org.joda.time.Interval; import org.junit.Assert; import org.junit.Before; @@ -592,7 +595,7 @@ public class ServerManagerTest } } - private static class SegmentForTesting implements Segment + private static class SegmentForTesting extends AbstractSegment { private final String version; private final Interval interval;