├── .gitignore
├── Code-of-Conduct.md
├── Contributing.md
├── LICENSE
├── Makefile
├── README.md
├── pom.xml
├── screwdriver.yaml
├── screwdriver
├── pubring.gpg.enc
├── release.sh
├── secring.gpg.enc
└── settings.xml
└── src
├── main
├── java
│ └── com
│ │ └── yahoo
│ │ └── bullet
│ │ ├── common
│ │ ├── BulletConfig.java
│ │ ├── BulletError.java
│ │ ├── BulletException.java
│ │ ├── Closable.java
│ │ ├── Config.java
│ │ ├── Configurable.java
│ │ ├── Initializable.java
│ │ ├── Monoidal.java
│ │ ├── RandomPool.java
│ │ ├── SerializerDeserializer.java
│ │ ├── Utilities.java
│ │ ├── Validator.java
│ │ └── metrics
│ │ │ ├── HTTPMetricEventPublisher.java
│ │ │ ├── HTTPMetricPublisherConfig.java
│ │ │ ├── MetricCollector.java
│ │ │ ├── MetricEvent.java
│ │ │ ├── MetricEventPublisher.java
│ │ │ └── MetricPublisher.java
│ │ ├── pubsub
│ │ ├── BufferingSubscriber.java
│ │ ├── BulletPubSubResponder.java
│ │ ├── ByteArrayPubSubMessageSerDe.java
│ │ ├── IdentityPubSubMessageSerDe.java
│ │ ├── Metadata.java
│ │ ├── PubSub.java
│ │ ├── PubSubException.java
│ │ ├── PubSubMessage.java
│ │ ├── PubSubMessageSerDe.java
│ │ ├── PubSubResponder.java
│ │ ├── Publisher.java
│ │ ├── Subscriber.java
│ │ └── rest
│ │ │ ├── RESTMetadata.java
│ │ │ ├── RESTPubSub.java
│ │ │ ├── RESTPubSubConfig.java
│ │ │ ├── RESTPublisher.java
│ │ │ ├── RESTQueryPublisher.java
│ │ │ ├── RESTResultPublisher.java
│ │ │ └── RESTSubscriber.java
│ │ ├── query
│ │ ├── Field.java
│ │ ├── Projection.java
│ │ ├── Query.java
│ │ ├── Window.java
│ │ ├── aggregations
│ │ │ ├── Aggregation.java
│ │ │ ├── AggregationType.java
│ │ │ ├── CountDistinct.java
│ │ │ ├── Distribution.java
│ │ │ ├── DistributionType.java
│ │ │ ├── GroupAll.java
│ │ │ ├── GroupBy.java
│ │ │ ├── LinearDistribution.java
│ │ │ ├── ManualDistribution.java
│ │ │ ├── Raw.java
│ │ │ ├── RegionDistribution.java
│ │ │ └── TopK.java
│ │ ├── expressions
│ │ │ ├── BinaryExpression.java
│ │ │ ├── CastExpression.java
│ │ │ ├── Expression.java
│ │ │ ├── FieldExpression.java
│ │ │ ├── ListExpression.java
│ │ │ ├── NAryExpression.java
│ │ │ ├── Operation.java
│ │ │ ├── UnaryExpression.java
│ │ │ └── ValueExpression.java
│ │ ├── postaggregations
│ │ │ ├── Computation.java
│ │ │ ├── Culling.java
│ │ │ ├── Having.java
│ │ │ ├── OrderBy.java
│ │ │ ├── PostAggregation.java
│ │ │ └── PostAggregationType.java
│ │ └── tablefunctions
│ │ │ ├── Explode.java
│ │ │ ├── LateralView.java
│ │ │ ├── OuterableTableFunction.java
│ │ │ ├── TableFunction.java
│ │ │ └── TableFunctionType.java
│ │ ├── querying
│ │ ├── Filter.java
│ │ ├── Projection.java
│ │ ├── Querier.java
│ │ ├── QueryCategorizer.java
│ │ ├── QueryManager.java
│ │ ├── RateLimitError.java
│ │ ├── RateLimiter.java
│ │ ├── RunningQuery.java
│ │ ├── aggregations
│ │ │ ├── FrequentItemsSketchingStrategy.java
│ │ │ ├── GroupAllStrategy.java
│ │ │ ├── KMVStrategy.java
│ │ │ ├── QuantileSketchingStrategy.java
│ │ │ ├── RawStrategy.java
│ │ │ ├── SketchingStrategy.java
│ │ │ ├── Strategy.java
│ │ │ ├── ThetaSketchingStrategy.java
│ │ │ ├── TupleSketchingStrategy.java
│ │ │ ├── grouping
│ │ │ │ ├── CachingGroupData.java
│ │ │ │ ├── GroupData.java
│ │ │ │ ├── GroupDataSummary.java
│ │ │ │ ├── GroupDataSummaryFactory.java
│ │ │ │ ├── GroupDataSummarySetOperations.java
│ │ │ │ └── GroupOperation.java
│ │ │ └── sketches
│ │ │ │ ├── DualSketch.java
│ │ │ │ ├── FrequentItemsSketch.java
│ │ │ │ ├── KMVSketch.java
│ │ │ │ ├── QuantileSketch.java
│ │ │ │ ├── Sketch.java
│ │ │ │ ├── ThetaSketch.java
│ │ │ │ └── TupleSketch.java
│ │ ├── evaluators
│ │ │ ├── BinaryEvaluator.java
│ │ │ ├── BinaryOperations.java
│ │ │ ├── CastEvaluator.java
│ │ │ ├── Evaluator.java
│ │ │ ├── FieldEvaluator.java
│ │ │ ├── ListEvaluator.java
│ │ │ ├── NAryEvaluator.java
│ │ │ ├── NAryOperations.java
│ │ │ ├── UnaryEvaluator.java
│ │ │ ├── UnaryOperations.java
│ │ │ └── ValueEvaluator.java
│ │ ├── partitioning
│ │ │ ├── Partitioner.java
│ │ │ └── SimpleEqualityPartitioner.java
│ │ ├── postaggregations
│ │ │ ├── ComputationStrategy.java
│ │ │ ├── CullingStrategy.java
│ │ │ ├── HavingStrategy.java
│ │ │ ├── OrderByStrategy.java
│ │ │ └── PostStrategy.java
│ │ └── tablefunctors
│ │ │ ├── ExplodeFunctor.java
│ │ │ ├── LateralViewBulletRecord.java
│ │ │ ├── LateralViewFunctor.java
│ │ │ ├── OuterableTableFunctor.java
│ │ │ └── TableFunctor.java
│ │ ├── result
│ │ ├── Clip.java
│ │ ├── JSONFormatter.java
│ │ └── Meta.java
│ │ ├── storage
│ │ ├── BaseStorageManager.java
│ │ ├── BaseStringStorageManager.java
│ │ ├── Criteria.java
│ │ ├── MemoryStorageManager.java
│ │ ├── MultiMemoryCountingCriteria.java
│ │ ├── MultiMemoryStorageManager.java
│ │ ├── NullStorageManager.java
│ │ ├── StorageConfig.java
│ │ └── StorageManager.java
│ │ └── windowing
│ │ ├── AdditiveTumbling.java
│ │ ├── Basic.java
│ │ ├── Scheme.java
│ │ ├── SlidingRecord.java
│ │ └── Tumbling.java
└── resources
│ ├── bullet_defaults.yaml
│ ├── checkstyle.xml
│ ├── copyright.txt
│ ├── log4j2.properties
│ └── rest_pubsub_defaults.yaml
└── test
├── java
└── com
│ └── yahoo
│ └── bullet
│ ├── TestHelpers.java
│ ├── common
│ ├── BulletConfigTest.java
│ ├── BulletErrorTest.java
│ ├── BulletExceptionTest.java
│ ├── RandomPoolTest.java
│ ├── SerializerDeserializerTest.java
│ ├── UtilitiesTest.java
│ ├── ValidatorTest.java
│ └── metrics
│ │ ├── HTTPMetricEventPublisherTest.java
│ │ ├── MetricCollectorTest.java
│ │ └── MetricEventPublisherTest.java
│ ├── pubsub
│ ├── BufferingSubscriberTest.java
│ ├── BulletPubSubResponderTest.java
│ ├── ByteArrayPubSubMessageSerDeTest.java
│ ├── IdentityPubSubMessageSerDeTest.java
│ ├── MetadataTest.java
│ ├── MockPubSub.java
│ ├── PubSubExceptionTest.java
│ ├── PubSubMessageTest.java
│ ├── PubSubResponderTest.java
│ ├── PubSubTest.java
│ ├── PublisherTest.java
│ ├── SubscriberTest.java
│ └── rest
│ │ ├── RESTMetadataTest.java
│ │ ├── RESTPubSubConfigTest.java
│ │ ├── RESTPubSubTest.java
│ │ ├── RESTQueryPublisherTest.java
│ │ ├── RESTResultPublisherTest.java
│ │ └── RESTSubscriberTest.java
│ ├── query
│ ├── FieldTest.java
│ ├── ProjectionTest.java
│ ├── QueryTest.java
│ ├── QueryUtils.java
│ ├── WindowTest.java
│ ├── WindowUtils.java
│ ├── aggregations
│ │ ├── CountDistinctTest.java
│ │ ├── DistributionTypeTest.java
│ │ ├── GroupAllTest.java
│ │ ├── GroupByTest.java
│ │ ├── LinearDistributionTest.java
│ │ ├── ManualDistributionTest.java
│ │ ├── RawTest.java
│ │ ├── RegionDistributionTest.java
│ │ └── TopKTest.java
│ ├── expressions
│ │ ├── BinaryExpressionTest.java
│ │ ├── CastExpressionTest.java
│ │ ├── ExpressionUtils.java
│ │ ├── FieldExpressionTest.java
│ │ ├── ListExpressionTest.java
│ │ ├── NAryExpressionTest.java
│ │ ├── UnaryExpressionTest.java
│ │ └── ValueExpressionTest.java
│ ├── postaggregations
│ │ ├── ComputationTest.java
│ │ ├── CullingTest.java
│ │ ├── HavingTest.java
│ │ └── OrderByTest.java
│ └── tablefunctions
│ │ ├── ExplodeTest.java
│ │ └── LateralViewTest.java
│ ├── querying
│ ├── FilterTest.java
│ ├── ProjectionTest.java
│ ├── QuerierTest.java
│ ├── QueryCategorizerTest.java
│ ├── QueryManagerTest.java
│ ├── RateLimitErrorTest.java
│ ├── RateLimiterTest.java
│ ├── RunningQueryTest.java
│ ├── aggregations
│ │ ├── AggregationUtils.java
│ │ ├── FrequentItemsSketchingStrategyTest.java
│ │ ├── GroupAllStrategyTest.java
│ │ ├── MockStrategy.java
│ │ ├── NoSerDeBulletRecord.java
│ │ ├── QuantileSketchingStrategyTest.java
│ │ ├── RawStrategyTest.java
│ │ ├── StrategyTest.java
│ │ ├── ThetaSketchingStrategyTest.java
│ │ ├── TupleSketchingStrategyTest.java
│ │ ├── grouping
│ │ │ ├── CachingGroupDataTest.java
│ │ │ ├── GroupDataSummaryFactoryTest.java
│ │ │ ├── GroupDataSummarySetOperationsTest.java
│ │ │ ├── GroupDataSummaryTest.java
│ │ │ ├── GroupDataTest.java
│ │ │ └── GroupOperationTest.java
│ │ └── sketches
│ │ │ ├── FrequentItemsSketchTest.java
│ │ │ ├── QuantileSketchTest.java
│ │ │ ├── ThetaSketchTest.java
│ │ │ └── TupleSketchTest.java
│ ├── evaluators
│ │ ├── BinaryEvaluatorTest.java
│ │ ├── BinaryOperationsTest.java
│ │ ├── CastEvaluatorTest.java
│ │ ├── EvaluatorUtils.java
│ │ ├── FieldEvaluatorTest.java
│ │ ├── ListEvaluatorTest.java
│ │ ├── NAryEvaluatorTest.java
│ │ ├── NAryOperationsTest.java
│ │ ├── UnaryEvaluatorTest.java
│ │ ├── UnaryOperationsTest.java
│ │ └── ValueEvaluatorTest.java
│ ├── partitioning
│ │ ├── MockPartitioner.java
│ │ └── SimpleEqualityPartitionerTest.java
│ ├── postaggregations
│ │ ├── ComputationStrategyTest.java
│ │ ├── CullingStrategyTest.java
│ │ ├── HavingStrategyTest.java
│ │ └── OrderByStrategyTest.java
│ └── tablefunctors
│ │ ├── ExplodeFunctorTest.java
│ │ ├── LateralViewBulletRecordTest.java
│ │ └── LateralViewFunctorTest.java
│ ├── result
│ ├── ClipTest.java
│ ├── JSONFormatterTest.java
│ ├── MetaTest.java
│ └── RecordBox.java
│ ├── storage
│ ├── MemoryStorageManagerTest.java
│ ├── MultiMemoryCountingCriteriaTest.java
│ ├── MultiMemoryStorageManagerTest.java
│ ├── NullStorageManagerTest.java
│ ├── StorageConfigTest.java
│ └── StorageManagerTest.java
│ └── windowing
│ ├── AdditiveTumblingTest.java
│ ├── BasicTest.java
│ ├── ClosableStrategy.java
│ ├── SlidingRecordTest.java
│ └── TumblingTest.java
└── resources
├── custom_config.yaml
├── empty_schema.json
├── log4j2.properties
├── storage_config.yaml
├── suppressions.xml
└── test_config.yaml
/.gitignore:
--------------------------------------------------------------------------------
1 | /target/**
2 | pom.xml.bak
3 |
--------------------------------------------------------------------------------
/Contributing.md:
--------------------------------------------------------------------------------
1 | # How to contribute
2 | First, thanks for taking the time to contribute to our project! The following information provides a guide for making contributions.
3 |
4 | ## Code of Conduct
5 |
6 | By participating in this project, you agree to abide by the [Yahoo Code of Conduct](Code-of-Conduct.md). Everyone is welcome to submit a pull request or open an issue to improve the documentation, add improvements, or report bugs.
7 |
8 | ## How to Ask a Question
9 |
10 | If you simply have a question that needs an answer, [create an issue](https://help.github.com/articles/creating-an-issue/), and label it as a question.
11 |
12 | ## How To Contribute
13 |
14 | ### Report a Bug or Request a Feature
15 |
16 | If you encounter any bugs while using this software, or want to request a new feature or enhancement, feel free to [create an issue](https://help.github.com/articles/creating-an-issue/) to report it, make sure you add a label to indicate what type of issue it is.
17 |
18 | ### Contribute Code
19 | Pull requests are welcome for bug fixes. If you want to implement something new, please [request a feature first](#report-a-bug-or-request-a-feature) so we can discuss it.
20 |
21 | #### Creating a Pull Request
22 | Before you submit any code, we need you to agree to our [Contributor License Agreement](https://yahoocla.herokuapp.com/); this ensures we can continue to protect your contributions under an open source license well into the future.
23 |
24 | Please follow [best practices](https://github.com/trein/dev-best-practices/wiki/Git-Commit-Best-Practices) for creating git commits.
25 |
26 | When your code is ready to be submitted, you can [submit a pull request](https://help.github.com/articles/creating-a-pull-request/) to begin the code review process.
27 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | all: full
2 |
3 | full:
4 | mvn clean javadoc:jar package
5 |
6 | clean:
7 | mvn clean
8 |
9 | test:
10 | mvn clean verify
11 |
12 | jar:
13 | mvn clean package
14 |
15 | release:
16 | mvn -B release:prepare release:clean
17 |
18 | coverage:
19 | mvn clean clover2:setup test clover2:aggregate clover2:clover
20 |
21 | doc:
22 | mvn clean javadoc:javadoc
23 |
24 | cc: see-coverage
25 |
26 | see-coverage: coverage
27 | cd target/site/clover; python -m SimpleHTTPServer
28 |
29 | cd: see-doc
30 |
31 | see-doc: doc
32 | cd target/site/apidocs; python -m SimpleHTTPServer
33 |
34 | fix-javadocs:
35 | mvn javadoc:fix -DfixClassComment=false -DfixFieldComment=false
36 |
37 |
--------------------------------------------------------------------------------
/screwdriver.yaml:
--------------------------------------------------------------------------------
1 | cache:
2 | pipeline: ["~/.m2"]
3 |
4 | shared:
5 | image: maven:3.6.3-jdk-8
6 |
7 | jobs:
8 | main:
9 | requires: [~pr, ~commit]
10 | secrets:
11 | - COVERALLS_TOKEN
12 | steps:
13 | - build: mvn -B clean verify
14 | - coverage: mvn coveralls:report
15 |
16 | release:
17 | requires: [~tag:/^bullet-core-\d+\.\d+\.\d+/]
18 | secrets:
19 | - SONATYPE_USERNAME
20 | - SONATYPE_PASSWORD
21 | - GPG_PASSPHRASE
22 | - GPG_ENCPHRASE
23 | steps:
24 | - publish: screwdriver/release.sh
25 |
26 |
--------------------------------------------------------------------------------
/screwdriver/pubring.gpg.enc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bullet-db/bullet-core/837f290ec27628b07f3ccc94d90bb0395c98176f/screwdriver/pubring.gpg.enc
--------------------------------------------------------------------------------
/screwdriver/release.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | export GPG_TTY=$(tty)
6 |
7 | openssl aes-256-cbc -pass pass:$GPG_ENCPHRASE -in screwdriver/pubring.gpg.enc -out screwdriver/pubring.gpg -d
8 | openssl aes-256-cbc -pass pass:$GPG_ENCPHRASE -in screwdriver/secring.gpg.enc -out screwdriver/secring.gpg -d
9 |
10 | mvn clean deploy --settings screwdriver/settings.xml -DskipTests=true -Possrh -Prelease
11 |
12 | rm -rf screwdriver/*.gpg
13 |
--------------------------------------------------------------------------------
/screwdriver/secring.gpg.enc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bullet-db/bullet-core/837f290ec27628b07f3ccc94d90bb0395c98176f/screwdriver/secring.gpg.enc
--------------------------------------------------------------------------------
/screwdriver/settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ossrh
5 | ${env.SONATYPE_USERNAME}
6 | ${env.SONATYPE_PASSWORD}
7 |
8 |
9 |
10 |
11 |
12 | ossrh
13 |
14 | true
15 |
16 |
17 | gpg
18 | ${env.GPG_PASSPHRASE}
19 | false
20 | ${env.SD_SOURCE_DIR}/screwdriver
21 | pubring.gpg
22 | secring.gpg
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/common/BulletError.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.common;
7 |
8 | import com.yahoo.bullet.result.JSONFormatter;
9 | import lombok.Getter;
10 | import lombok.RequiredArgsConstructor;
11 |
12 | import java.io.Serializable;
13 | import java.util.HashMap;
14 | import java.util.List;
15 | import java.util.Map;
16 |
17 | import static java.util.Collections.singletonList;
18 |
19 | @Getter @RequiredArgsConstructor
20 | public class BulletError implements JSONFormatter, Serializable {
21 | private static final long serialVersionUID = -8557063189698127685L;
22 |
23 | public static final String ERROR_KEY = "error";
24 | public static final String RESOLUTIONS_KEY = "resolutions";
25 |
26 | private final String error;
27 | private final List resolutions;
28 |
29 | /**
30 | * Creates a BulletError with the given error message and resolution.
31 | *
32 | * @param error The message denoting the error.
33 | * @param resolution A resolution message.
34 | */
35 | public BulletError(String error, String resolution) {
36 | this(error, singletonList(resolution));
37 | }
38 |
39 | @Override
40 | public String asJSON() {
41 | Map map = new HashMap<>();
42 | map.put(ERROR_KEY, error);
43 | map.put(RESOLUTIONS_KEY, resolutions);
44 | return JSONFormatter.asJSON(map);
45 | }
46 |
47 | /**
48 | * Creates a BulletError with the given error message and resolution.
49 | *
50 | * @param error The message denoting the error.
51 | * @param resolution A resolution message.
52 | *
53 | * @return A BulletError representing this cause.
54 | */
55 | public static BulletError makeError(String error, String resolution) {
56 | return new BulletError(error, resolution);
57 | }
58 |
59 | @Override
60 | public String toString() {
61 | return "{error: " + error + ", resolutions: " + resolutions + "}";
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/common/BulletException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.common;
7 |
8 | import lombok.AllArgsConstructor;
9 | import lombok.Getter;
10 |
11 | @Getter @AllArgsConstructor
12 | public class BulletException extends RuntimeException {
13 | private static final long serialVersionUID = 2868933191828758133L;
14 |
15 | private BulletError error;
16 |
17 | /**
18 | * Creates a BulletException from an error and resolution.
19 | *
20 | * @param error The error message.
21 | * @param resolution The resolution message.
22 | */
23 | public BulletException(String error, String resolution) {
24 | this.error = new BulletError(error, resolution);
25 | }
26 |
27 | @Override
28 | public String getMessage() {
29 | return error.getError();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/common/Closable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.common;
7 |
8 | public interface Closable {
9 | /**
10 | * Returns true if this is currently closed.
11 | *
12 | * @return A boolean denoting whether this object is current closed.
13 | */
14 | boolean isClosed();
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/common/Configurable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.common;
7 |
8 | public interface Configurable {
9 | /**
10 | * Takes a {@link BulletConfig} containing configuration and applies it to itself.
11 | *
12 | * @param configuration The configuration containing the settings.
13 | */
14 | void configure(BulletConfig configuration);
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/common/Initializable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.common;
7 |
8 | import java.util.List;
9 | import java.util.Optional;
10 |
11 | public interface Initializable {
12 | /**
13 | * Validates and initializes this object.
14 | *
15 | * @return An {@link Optional} {@link List} of {@link BulletError} in this object or its constituents.
16 | */
17 | Optional> initialize();
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/common/RandomPool.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.common;
7 |
8 | import java.util.List;
9 | import java.util.Random;
10 |
11 | public class RandomPool {
12 | private List items;
13 |
14 | private static final Random RANDOM = new Random();
15 |
16 | /**
17 | * Constructor for the RandomPool that takes a list of items.
18 | * @param items A list of items to form the pool with.
19 | */
20 | public RandomPool(List items) {
21 | this.items = items;
22 | }
23 |
24 | /**
25 | * Get a random item from the pool.
26 | *
27 | * @return a randomly chosen item from the pool.
28 | */
29 | public T get() {
30 | if (items == null || items.isEmpty()) {
31 | return null;
32 | }
33 | return items.get(RANDOM.nextInt(items.size()));
34 | }
35 |
36 | /**
37 | * Clear the RandomPool. Gets now return null.
38 | */
39 | public void clear() {
40 | items = null;
41 | }
42 |
43 | @Override
44 | public String toString() {
45 | return items == null ? null : items.toString();
46 | }
47 |
48 | @Override
49 | public boolean equals(Object object) {
50 | if (this == object) {
51 | return true;
52 | }
53 | if (object == null) {
54 | return false;
55 | }
56 | if (!(object instanceof RandomPool)) {
57 | return false;
58 | }
59 | RandomPool asPool = (RandomPool) object;
60 | return items == null ? asPool.items == null : items.equals(asPool.items);
61 | }
62 |
63 | @Override
64 | public int hashCode() {
65 | // Any number would do since we want RandomPools of null to be equal to each other.
66 | return items == null ? 42 : items.hashCode();
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/common/SerializerDeserializer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.common;
7 |
8 | import lombok.extern.slf4j.Slf4j;
9 |
10 | import java.io.ByteArrayInputStream;
11 | import java.io.ByteArrayOutputStream;
12 | import java.io.IOException;
13 | import java.io.ObjectInputStream;
14 | import java.io.ObjectOutputStream;
15 | import java.io.Serializable;
16 |
17 | @Slf4j
18 | public class SerializerDeserializer {
19 | /**
20 | * Convenience method to deserialize an object into a type from raw serialized data produced by the method
21 | * {@link #toBytes(Serializable)}.
22 | *
23 | * @param data The raw serialized byte[] representing the data.
24 | * @param The class to try to get the data as.
25 | * @return A reified object or null if not successful.
26 | */
27 | public static U fromBytes(byte[] data) {
28 | try (
29 | ByteArrayInputStream bis = new ByteArrayInputStream(data);
30 | ObjectInputStream ois = new ObjectInputStream(bis)
31 | ) {
32 | return (U) ois.readObject();
33 | } catch (IOException | ClassNotFoundException | RuntimeException e) {
34 | log.error("Could not reify an Object from raw data {}", data);
35 | log.error("Exception was: ", e);
36 | }
37 | return null;
38 | }
39 |
40 | /**
41 | * Convenience method to serializes the given {@link Serializable} object to a raw byte[].
42 | *
43 | * @param object The object to serialize.
44 | * @param The subtype of {@link Serializable} to try and serialize.
45 | * @return the serialized byte[] or null if not successful.
46 | */
47 | public static byte[] toBytes(U object) {
48 | try (
49 | ByteArrayOutputStream bos = new ByteArrayOutputStream();
50 | ObjectOutputStream oos = new ObjectOutputStream(bos)
51 | ) {
52 | oos.writeObject(object);
53 | return bos.toByteArray();
54 | } catch (IOException | RuntimeException e) {
55 | log.error("Could not serialize given object {}", object);
56 | log.error("Exception was: ", e);
57 | }
58 | return null;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/common/metrics/MetricEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.common.metrics;
7 |
8 | import com.yahoo.bullet.result.JSONFormatter;
9 | import lombok.Getter;
10 |
11 | import java.util.Map;
12 |
13 | /**
14 | * Simple wrapper that represents a metric event being published.
15 | */
16 | @Getter
17 | public class MetricEvent implements JSONFormatter {
18 | private final String group;
19 | private final long timestamp;
20 | private final Map dimensions;
21 | private final Map metrics;
22 |
23 | /**
24 | * Constructor.
25 | *
26 | * @param group The identity of the entity being measured by the metrics.
27 | * @param dimensions Static metadata or tags describing the entity being measured.
28 | * @param metrics Numeric data describing values of the measured entity.
29 | */
30 | public MetricEvent(String group, Map dimensions, Map metrics) {
31 | this.group = group;
32 | this.dimensions = dimensions;
33 | this.metrics = metrics;
34 | this.timestamp = System.currentTimeMillis();
35 | }
36 |
37 | @Override
38 | public String asJSON() {
39 | return JSONFormatter.asJSON(this);
40 | }
41 | }
42 |
43 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/common/metrics/MetricEventPublisher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.common.metrics;
7 |
8 | import com.yahoo.bullet.common.BulletConfig;
9 |
10 | import java.util.Map;
11 |
12 | /**
13 | * This class concretizes {@link MetricPublisher} with {@link MetricEvent}.
14 | */
15 | public abstract class MetricEventPublisher extends MetricPublisher {
16 | public static String DEFAULT_GROUP = "default";
17 |
18 | /**
19 | * Constructor taking a {@link BulletConfig}.
20 | *
21 | * @param config The config to use containing the necessary information.
22 | */
23 | public MetricEventPublisher(BulletConfig config) {
24 | super(config);
25 | }
26 |
27 | /**
28 | * Get the group to use for the {@link MetricEvent}. By default, uses {@link #DEFAULT_GROUP}.
29 | *
30 | * @return The group to use for the {@link MetricEvent}.
31 | */
32 | public String getGroup() {
33 | return DEFAULT_GROUP;
34 | }
35 |
36 | @Override
37 | public MetricEvent convert(Map dimensions, Map metrics) {
38 | return new MetricEvent(getGroup(), dimensions, metrics);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/pubsub/BulletPubSubResponder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.pubsub;
7 |
8 | import com.yahoo.bullet.common.BulletConfig;
9 | import lombok.extern.slf4j.Slf4j;
10 |
11 | /**
12 | * Use this as a {@link PubSubResponder} if async results should be sent to a {@link PubSub} interface. This simply
13 | * creates an instance of a {@link PubSub} from your provided {@link BulletConfig} and tries to create a
14 | * {@link Publisher} from it to respond with results to.
15 | */
16 | @Slf4j
17 | public class BulletPubSubResponder extends PubSubResponder {
18 | protected PubSub pubSub;
19 | protected Publisher publisher;
20 |
21 | /**
22 | * Constructor.
23 | *
24 | * @param config The {@link BulletConfig} to use.
25 | */
26 | public BulletPubSubResponder(BulletConfig config) {
27 | super(config);
28 | try {
29 | pubSub = PubSub.from(config);
30 | publisher = pubSub.getPublisher();
31 | } catch (Exception e) {
32 | throw new RuntimeException("Unable to create a PubSub instance or a Publisher from it", e);
33 | }
34 | }
35 |
36 | @Override
37 | public void respond(String id, PubSubMessage message) {
38 | log.debug("Responding with message {}", id);
39 | log.trace("Responding to {} with payload {}", id, message);
40 | try {
41 | publisher.send(message);
42 | } catch (PubSubException e) {
43 | log.error("Unable to publish message. Ignoring {}: {}", id, message);
44 | log.error("Error", e);
45 | }
46 | }
47 |
48 | @Override
49 | public void close() {
50 | try {
51 | publisher.close();
52 | } catch (Exception e) {
53 | log.error("Unable to close the publisher", e);
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/pubsub/IdentityPubSubMessageSerDe.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.pubsub;
7 |
8 | import com.yahoo.bullet.common.BulletConfig;
9 |
10 | public class IdentityPubSubMessageSerDe extends PubSubMessageSerDe {
11 | private static final long serialVersionUID = -1709000962888195381L;
12 |
13 | /**
14 | * Constructor.
15 | *
16 | * @param config The {@link BulletConfig} to configure this class.
17 | */
18 | public IdentityPubSubMessageSerDe(BulletConfig config) {
19 | super(config);
20 | }
21 |
22 | @Override
23 | public PubSubMessage toMessage(PubSubMessage message) {
24 | return message;
25 | }
26 |
27 | @Override
28 | public PubSubMessage fromMessage(PubSubMessage message) {
29 | return message;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/pubsub/PubSubException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.pubsub;
7 |
8 | /**
9 | * Exception to be thrown if there is an error in {@link PubSub}, {@link Publisher} or {@link Subscriber}.
10 | */
11 | public class PubSubException extends Exception {
12 | /**
13 | * Constructor to initialize PubSubException with a message.
14 | *
15 | * @param message The error message to be associated with the PubSubException.
16 | */
17 | public PubSubException(String message) {
18 | super(message);
19 | }
20 |
21 | /**
22 | * Constructor to initialize PubSubException with a message and a {@link Throwable} cause.
23 | *
24 | * @param message The error message to be associated with the PubSubException.
25 | * @param cause The reason for the PubSubException.
26 | */
27 | public PubSubException(String message, Throwable cause) {
28 | super(message, cause);
29 | }
30 |
31 | /**
32 | * Method to create a PubSubException when a required argument could not be read.
33 | *
34 | * @param name The name of the argument that could not be read.
35 | * @param cause The optional {@link Throwable} that caused the exception.
36 | * @return A PubSubException indicating failure to read a required argument.
37 | */
38 | public static PubSubException forArgument(String name, Throwable cause) {
39 | String message = "Could not read required argument: " + name;
40 | return cause == null ? new PubSubException(message) : new PubSubException(message, cause);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/pubsub/PubSubResponder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.pubsub;
7 |
8 | import com.yahoo.bullet.common.BulletConfig;
9 | import lombok.extern.slf4j.Slf4j;
10 |
11 | /**
12 | * This can be extended by any class that needs to respond to a {@link PubSubMessage}.
13 | */
14 | @Slf4j
15 | public abstract class PubSubResponder implements AutoCloseable {
16 | protected BulletConfig config;
17 |
18 | /**
19 | * Constructor.
20 | *
21 | * @param config The {@link BulletConfig} to use.
22 | */
23 | public PubSubResponder(BulletConfig config) {
24 | this.config = config;
25 | }
26 |
27 | /**
28 | * Respond to a {@link PubSubMessage}.
29 | *
30 | * @param id The id of the response.
31 | * @param message The actual {@link PubSubMessage} containing the response.
32 | */
33 | public abstract void respond(String id, PubSubMessage message);
34 |
35 | @Override
36 | public void close() {
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/pubsub/Publisher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.pubsub;
7 |
8 | import java.io.Serializable;
9 |
10 | public interface Publisher extends AutoCloseable {
11 | /**
12 | * Send a message with an ID and content.
13 | *
14 | * @param id The ID associated with the message.
15 | * @param content The content of the message.
16 | * @return The sent {@link PubSubMessage}.
17 | * @throws PubSubException if the messaging system throws an error.
18 | */
19 | default PubSubMessage send(String id, Serializable content) throws PubSubException {
20 | return send(new PubSubMessage(id, content));
21 | }
22 |
23 | /**
24 | * Sends a {@link PubSubMessage}. The message might be modified so the sent message is returned.
25 | *
26 | * @param message The {@link PubSubMessage} to be sent.
27 | * @return The sent {@link PubSubMessage}.
28 | * @throws PubSubException if the messaging system throws an error.
29 | */
30 | PubSubMessage send(PubSubMessage message) throws PubSubException;
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/pubsub/Subscriber.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.pubsub;
7 |
8 | public interface Subscriber extends AutoCloseable {
9 | /**
10 | * Gets a new {@link PubSubMessage} from the assigned partition/partitions (Here a partition is a unit of
11 | * parallelism in the Pub/Sub queue, See {@link PubSub}).
12 | *
13 | * @return the received {@link PubSubMessage}.
14 | * @throws PubSubException when a receive fails.
15 | */
16 | PubSubMessage receive() throws PubSubException;
17 |
18 | /**
19 | * Commits allow clients to implement at least once, at most once or exactly once semantics when processing messages.
20 | *
21 | * Common implementations might
22 | * 1. Ack all received messages.
23 | * 2. Commit current read offset to persistent/fault tolerant storage.
24 | *
25 | * @param id The ID of the message to be marked as committed.
26 | */
27 | void commit(String id);
28 |
29 | /**
30 | * Marks the processing of the {@link PubSubMessage} with the given id as failed.
31 | *
32 | * @param id The ID of the PubSubMessage to mark as a processing failure.
33 | */
34 | void fail(String id);
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/pubsub/rest/RESTMetadata.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.pubsub.rest;
7 |
8 | import com.yahoo.bullet.pubsub.Metadata;
9 | import lombok.Getter;
10 | import lombok.RequiredArgsConstructor;
11 |
12 | @RequiredArgsConstructor
13 | class RESTMetadata extends Metadata {
14 | private static final long serialVersionUID = 5718947090573796171L;
15 | @Getter
16 | private final String url;
17 |
18 | /**
19 | * Only for use within the RESTPubSub.
20 | *
21 | * @param url The URL to use to identify where to send messages to.
22 | * @param metadata An instance of a {@link Metadata} to wrap.
23 | */
24 | RESTMetadata(String url, Metadata metadata) {
25 | super(metadata.getSignal(), metadata.getContent());
26 | this.url = url;
27 | }
28 |
29 | @Override
30 | public Metadata copy() {
31 | return new RESTMetadata(url, this);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/pubsub/rest/RESTQueryPublisher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.pubsub.rest;
7 |
8 | import com.yahoo.bullet.pubsub.Metadata;
9 | import com.yahoo.bullet.pubsub.PubSubMessage;
10 | import lombok.AccessLevel;
11 | import lombok.Getter;
12 | import lombok.extern.slf4j.Slf4j;
13 | import org.apache.http.impl.client.CloseableHttpClient;
14 |
15 | @Slf4j
16 | public class RESTQueryPublisher extends RESTPublisher {
17 | @Getter(AccessLevel.PACKAGE)
18 | private String queryURL;
19 | private String resultURL;
20 |
21 | /**
22 | * Create a RESTQueryPublisher from a {@link CloseableHttpClient}, queryURL and resultURL. The BulletConfig must
23 | * contain a valid url in the bullet.pubsub.rest.query.urls field.
24 | *
25 | * @param client The client.
26 | * @param queryURL The URL to which to POST queries.
27 | * @param resultURL The URL that will be added to the Metadata (results will be sent to this URL from the backend).
28 | * @param connectTimeout The minimum time (ms) to wait for a connection to be made.
29 | */
30 | public RESTQueryPublisher(CloseableHttpClient client, String queryURL, String resultURL, int connectTimeout) {
31 | super(client, connectTimeout);
32 | this.queryURL = queryURL;
33 | this.resultURL = resultURL;
34 | }
35 |
36 | @Override
37 | public PubSubMessage send(PubSubMessage message) {
38 | // Put resultURL in the metadata so the ResponsePublisher knows to which host to send the response
39 | Metadata metadata = message.getMetadata();
40 | metadata = metadata == null ? new RESTMetadata(resultURL) : new RESTMetadata(resultURL, metadata);
41 | message.setMetadata(metadata);
42 | sendToURL(queryURL, message);
43 | return message;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/pubsub/rest/RESTResultPublisher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.pubsub.rest;
7 |
8 | import com.yahoo.bullet.pubsub.PubSubMessage;
9 | import lombok.extern.slf4j.Slf4j;
10 | import org.apache.http.impl.client.CloseableHttpClient;
11 |
12 | @Slf4j
13 | public class RESTResultPublisher extends RESTPublisher {
14 | /**
15 | * Create a RESTQueryPublisher from a {@link CloseableHttpClient}.
16 | *
17 | * @param client The client.
18 | * @param connectTimeout The minimum time (ms) to wait for a connection to be made.
19 | */
20 | public RESTResultPublisher(CloseableHttpClient client, int connectTimeout) {
21 | super(client, connectTimeout);
22 | }
23 |
24 | @Override
25 | public PubSubMessage send(PubSubMessage message) {
26 | String url = ((RESTMetadata) message.getMetadata()).getUrl();
27 | log.debug("Extracted url to send results to: {}", url);
28 | sendToURL(url, message);
29 | return message;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/Field.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query;
7 |
8 | import com.yahoo.bullet.query.expressions.Expression;
9 | import lombok.Getter;
10 |
11 | import java.io.Serializable;
12 | import java.util.Objects;
13 |
14 | @Getter
15 | public class Field implements Serializable {
16 | private static final long serialVersionUID = -2084429671585261042L;
17 |
18 | private String name;
19 | private Expression value;
20 |
21 | /**
22 | * Constructor that creates a field used in projection and computation.
23 | *
24 | * @param name The non-null name of the field.
25 | * @param value The non-null value of the field.
26 | */
27 | public Field(String name, Expression value) {
28 | this.name = Objects.requireNonNull(name);
29 | this.value = Objects.requireNonNull(value);
30 | }
31 |
32 | @Override
33 | public boolean equals(Object obj) {
34 | if (obj == this) {
35 | return true;
36 | }
37 | if (!(obj instanceof Field)) {
38 | return false;
39 | }
40 | Field other = (Field) obj;
41 | return Objects.equals(name, other.name) && Objects.equals(value, other.value);
42 | }
43 |
44 | @Override
45 | public int hashCode() {
46 | return Objects.hash(name, value);
47 | }
48 |
49 | @Override
50 | public String toString() {
51 | return "{name: " + name + ", value: " + value + "}";
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/Projection.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query;
7 |
8 | import com.yahoo.bullet.common.Utilities;
9 | import lombok.Getter;
10 | import lombok.extern.slf4j.Slf4j;
11 |
12 | import java.io.Serializable;
13 | import java.util.List;
14 |
15 | @Slf4j @Getter
16 | public class Projection implements Serializable {
17 | private static final long serialVersionUID = -9194169391843941958L;
18 |
19 | /**
20 | * The type of the Projection decides how its fields are projected.
21 | */
22 | public enum Type {
23 | COPY, // Projects onto a copy of the original record
24 | NO_COPY, // Projects onto a new record
25 | PASS_THROUGH // Passes the original record through
26 | }
27 |
28 | private final List fields;
29 | private final Type type;
30 |
31 | /**
32 | * Default constructor that creates a PASS_THROUGH projection.
33 | */
34 | public Projection() {
35 | fields = null;
36 | type = Type.PASS_THROUGH;
37 | }
38 |
39 | /**
40 | * Constructor that creates a COPY or NO_COPY projection.
41 | *
42 | * @param fields The list of fields to project. Must not be null or contain null fields.
43 | * @param copy Whether the projection should copy or not copy.
44 | */
45 | public Projection(List fields, boolean copy) {
46 | this.fields = Utilities.requireNonNull(fields);
47 | this.type = copy ? Type.COPY : Type.NO_COPY;
48 | }
49 |
50 | @Override
51 | public String toString() {
52 | return "{fields: " + fields + ", type: " + type + "}";
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/aggregations/Aggregation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.aggregations;
7 |
8 | import com.yahoo.bullet.common.BulletConfig;
9 | import com.yahoo.bullet.common.Configurable;
10 | import com.yahoo.bullet.querying.aggregations.Strategy;
11 | import lombok.AllArgsConstructor;
12 | import lombok.Getter;
13 |
14 | import java.io.Serializable;
15 | import java.util.Collections;
16 | import java.util.List;
17 |
18 | @Getter @AllArgsConstructor
19 | public abstract class Aggregation implements Configurable, Serializable {
20 | private static final long serialVersionUID = -4451469769203362270L;
21 |
22 | protected Integer size;
23 | protected final AggregationType type;
24 |
25 | @Override
26 | public void configure(BulletConfig config) {
27 | int sizeDefault = config.getAs(BulletConfig.AGGREGATION_DEFAULT_SIZE, Integer.class);
28 | int sizeMaximum = config.getAs(BulletConfig.AGGREGATION_MAX_SIZE, Integer.class);
29 |
30 | // Null or not positive, then default, else min of size and max
31 | size = (size == null || size <= 0) ? sizeDefault : Math.min(size, sizeMaximum);
32 | }
33 |
34 | /**
35 | * Returns a new {@link Strategy} instance that handles this aggregation.
36 | *
37 | * @param config The {@link BulletConfig} containing configuration for the strategy.
38 | * @return The created instance of a strategy that can implement this aggregation.
39 | */
40 | public abstract Strategy getStrategy(BulletConfig config);
41 |
42 | /**
43 | * Gets the aggregation fields.
44 | *
45 | * @return The aggregation fields.
46 | */
47 | public List getFields() {
48 | return Collections.emptyList();
49 | }
50 |
51 | @Override
52 | public String toString() {
53 | return "{size: " + size + ", type: " + type + "}";
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/aggregations/AggregationType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.aggregations;
7 |
8 | /**
9 | * Represents the type of the {@link Aggregation}.
10 | */
11 | public enum AggregationType {
12 | GROUP,
13 | COUNT_DISTINCT,
14 | TOP_K,
15 | DISTRIBUTION,
16 | RAW
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/aggregations/CountDistinct.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.aggregations;
7 |
8 | import com.yahoo.bullet.querying.aggregations.ThetaSketchingStrategy;
9 | import com.yahoo.bullet.querying.aggregations.Strategy;
10 | import com.yahoo.bullet.common.BulletConfig;
11 | import com.yahoo.bullet.common.BulletException;
12 | import com.yahoo.bullet.common.Utilities;
13 | import lombok.Getter;
14 |
15 | import java.util.List;
16 | import java.util.Objects;
17 |
18 | @Getter
19 | public class CountDistinct extends Aggregation {
20 | private static final long serialVersionUID = 3079494553075374672L;
21 | private static final BulletException COUNT_DISTINCT_REQUIRES_FIELDS =
22 | new BulletException("COUNT DISTINCT requires at least one field.", "Please add at least one field.");
23 |
24 | private final List fields;
25 | private final String name;
26 |
27 | /**
28 | * Constructor that creates a COUNT_DISTINCT aggregation.
29 | *
30 | * @param fields The list of fields to count distinct on.
31 | * @param name The name of the count distinct field.
32 | */
33 | public CountDistinct(List fields, String name) {
34 | super(null, AggregationType.COUNT_DISTINCT);
35 | Utilities.requireNonNull(fields);
36 | if (fields.isEmpty()) {
37 | throw COUNT_DISTINCT_REQUIRES_FIELDS;
38 | }
39 | this.fields = fields;
40 | this.name = Objects.requireNonNull(name);
41 | }
42 |
43 | @Override
44 | public Strategy getStrategy(BulletConfig config) {
45 | return new ThetaSketchingStrategy(this, config);
46 | }
47 |
48 | @Override
49 | public String toString() {
50 | return "{size: " + size + ", type: " + type + ", fields: " + fields + ", name: " + name + "}";
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/aggregations/Distribution.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.aggregations;
7 |
8 | import com.yahoo.bullet.querying.aggregations.QuantileSketchingStrategy;
9 | import com.yahoo.bullet.querying.aggregations.Strategy;
10 | import com.yahoo.bullet.common.BulletConfig;
11 | import lombok.Getter;
12 |
13 | import java.util.Collections;
14 | import java.util.List;
15 | import java.util.Objects;
16 |
17 | @Getter
18 | public abstract class Distribution extends Aggregation {
19 | private static final long serialVersionUID = -7862051610403543796L;
20 |
21 | protected final String field;
22 | protected final DistributionType distributionType;
23 |
24 | /**
25 | * Constructor that creates a DISTRIBUTION aggregation with a specified max size.
26 | *
27 | * @param field The non-null field
28 | * @param type The non-null distribution type
29 | * @param size The max size of the DISTRIBUTION aggregation. Can be null.
30 | */
31 | protected Distribution(String field, DistributionType type, Integer size) {
32 | super(size, AggregationType.DISTRIBUTION);
33 | this.field = Objects.requireNonNull(field, "The field must be non-null.");
34 | this.distributionType = Objects.requireNonNull(type, "The distribution type must be non-null.");
35 | }
36 |
37 | @Override
38 | public Strategy getStrategy(BulletConfig config) {
39 | return new QuantileSketchingStrategy(this, config);
40 | }
41 |
42 | @Override
43 | public List getFields() {
44 | return Collections.singletonList(field);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/aggregations/DistributionType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.aggregations;
7 |
8 | import lombok.AllArgsConstructor;
9 | import lombok.Getter;
10 |
11 | @Getter @AllArgsConstructor
12 | public enum DistributionType {
13 | QUANTILE("QUANTILE"),
14 | PMF("FREQ"),
15 | CDF("CUMFREQ");
16 |
17 | private String name;
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/aggregations/GroupAll.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.aggregations;
7 |
8 | import com.yahoo.bullet.common.BulletConfig;
9 | import com.yahoo.bullet.common.BulletException;
10 | import com.yahoo.bullet.common.Utilities;
11 | import com.yahoo.bullet.querying.aggregations.GroupAllStrategy;
12 | import com.yahoo.bullet.querying.aggregations.Strategy;
13 | import com.yahoo.bullet.querying.aggregations.grouping.GroupOperation;
14 | import lombok.Getter;
15 |
16 | import java.util.Set;
17 |
18 | @Getter
19 | public class GroupAll extends Aggregation {
20 | private static final long serialVersionUID = 5118426551573371428L;
21 | private static final BulletException COUNT_FIELD_INVALID_OPERATION =
22 | new BulletException("COUNT_FIELD is not a valid operation.", "Please remove this operation.");
23 |
24 | private final Set operations;
25 |
26 | /**
27 | * Constructor that creates a GROUP aggregation with a set of group operations.
28 | *
29 | * @param operations The non-null set of group operations.
30 | */
31 | public GroupAll(Set operations) {
32 | super(null, AggregationType.GROUP);
33 | Utilities.requireNonNull(operations);
34 | if (operations.stream().anyMatch(operation -> operation.getType() == GroupOperation.GroupOperationType.COUNT_FIELD)) {
35 | throw COUNT_FIELD_INVALID_OPERATION;
36 | }
37 | this.operations = operations;
38 | }
39 |
40 | @Override
41 | public Strategy getStrategy(BulletConfig config) {
42 | return new GroupAllStrategy(this, config);
43 | }
44 |
45 | @Override
46 | public String toString() {
47 | return "{size: " + size + ", type: " + type + ", operations: " + operations + "}";
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/aggregations/LinearDistribution.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.aggregations;
7 |
8 | import com.yahoo.bullet.common.BulletException;
9 | import lombok.Getter;
10 |
11 | @Getter
12 | public class LinearDistribution extends Distribution {
13 | private static final long serialVersionUID = -5320252906943658246L;
14 | private static final BulletException NUMBER_OF_POINTS_MUST_BE_POSITIVE =
15 | new BulletException("If specifying the distribution by the number of points, the number must be positive.", "Please specify a positive number.");
16 |
17 | private final int numberOfPoints;
18 |
19 | /**
20 | * Constructor that creates a DISTRIBUTION aggregation with a specified max size. The number of equidistant
21 | * points in this distribution are specified.
22 | *
23 | * @param field The non-null field.
24 | * @param type The non-null distribution type.
25 | * @param size The max size of the DISTRIBUTION aggregation. Can be null.
26 | * @param numberOfPoints The number of equidistant points for this distribution.
27 | */
28 | public LinearDistribution(String field, DistributionType type, Integer size, int numberOfPoints) {
29 | super(field, type, size);
30 | if (numberOfPoints <= 0) {
31 | throw NUMBER_OF_POINTS_MUST_BE_POSITIVE;
32 | }
33 | this.numberOfPoints = numberOfPoints;
34 | }
35 |
36 | @Override
37 | public String toString() {
38 | return "{size: " + size + ", type: " + type + ", field: " + field + ", distributionType: " + distributionType + ", numberOfPoints: " + numberOfPoints + "}";
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/aggregations/ManualDistribution.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.aggregations;
7 |
8 | import com.yahoo.bullet.common.BulletException;
9 | import com.yahoo.bullet.common.Utilities;
10 | import lombok.Getter;
11 |
12 | import java.util.ArrayList;
13 | import java.util.List;
14 | import java.util.stream.Collectors;
15 |
16 | @Getter
17 | public class ManualDistribution extends Distribution {
18 | private static final long serialVersionUID = 7022392121466809427L;
19 | private static final BulletException MANUAL_DISTRIBUTION_MISSING_POINTS =
20 | new BulletException("If specifying the distribution by a list of points, the list must contain at least one point.",
21 | "Please specify at least one point.");
22 | private static final BulletException QUANTILE_POINTS_INVALID_RANGE =
23 | new BulletException("The QUANTILE distribution requires points to be within the interval [0, 1] inclusive.",
24 | "Please specify a list of valid points.");
25 |
26 |
27 | private final List points;
28 |
29 | /**
30 | * Constructor that creates a DISTRIBUTION aggregation with a specified max size. The points in this distribution
31 | * are specified manually.
32 | *
33 | * @param field The non-null field.
34 | * @param type The non-null distribution type.
35 | * @param size The max size of the DISTRIBUTION aggregation. Can be null.
36 | * @param points The points of the distribution. Must be not be empty.
37 | */
38 | public ManualDistribution(String field, DistributionType type, Integer size, List points) {
39 | super(field, type, size);
40 | Utilities.requireNonNull(points);
41 | if (points.isEmpty()) {
42 | throw MANUAL_DISTRIBUTION_MISSING_POINTS;
43 | }
44 | if (isListInvalid(points, type)) {
45 | throw QUANTILE_POINTS_INVALID_RANGE;
46 | }
47 | this.points = points.stream().distinct().sorted().collect(Collectors.toCollection(ArrayList::new));
48 | }
49 |
50 | private static boolean isListInvalid(List points, DistributionType type) {
51 | // if type is QUANTILE, invalid range if start < 0 or end > 1
52 | return type == DistributionType.QUANTILE && (points.get(0) < 0.0 || points.get(points.size() - 1) > 1.0);
53 | }
54 |
55 | @Override
56 | public String toString() {
57 | return "{size: " + size + ", type: " + type + ", field: " + field + ", distributionType: " + distributionType + ", points: " + points + "}";
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/aggregations/Raw.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.aggregations;
7 |
8 | import com.yahoo.bullet.common.BulletConfig;
9 | import com.yahoo.bullet.querying.aggregations.RawStrategy;
10 | import com.yahoo.bullet.querying.aggregations.Strategy;
11 |
12 | public class Raw extends Aggregation {
13 | private static final long serialVersionUID = -589592577885076012L;
14 |
15 | /**
16 | * Constructor that creates a RAW aggregation with a specified max size.
17 | *
18 | * @param size The max size of the RAW aggregation. Can be null.
19 | */
20 | public Raw(Integer size) {
21 | super(size, AggregationType.RAW);
22 | }
23 |
24 | @Override
25 | public Strategy getStrategy(BulletConfig config) {
26 | return new RawStrategy(this, config);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/aggregations/TopK.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.aggregations;
7 |
8 | import com.yahoo.bullet.querying.aggregations.FrequentItemsSketchingStrategy;
9 | import com.yahoo.bullet.querying.aggregations.Strategy;
10 | import com.yahoo.bullet.common.BulletConfig;
11 | import com.yahoo.bullet.common.BulletException;
12 | import com.yahoo.bullet.common.Utilities;
13 | import lombok.Getter;
14 |
15 | import java.util.ArrayList;
16 | import java.util.List;
17 | import java.util.Map;
18 | import java.util.Objects;
19 |
20 | @Getter
21 | public class TopK extends Aggregation {
22 | private static final long serialVersionUID = 2934123789816778466L;
23 | private static final BulletException TOP_K_REQUIRES_FIELDS =
24 | new BulletException("TOP K requires at least one field.", "Please add at least one field.");
25 |
26 | private final Map fieldsToNames;
27 | private final Long threshold;
28 | private final String name;
29 |
30 | /**
31 | * Constructor that creates a TOP_K aggregation with a specified max size.
32 | *
33 | * @param fieldsToNames The mapping of fields to aliases of the Top K aggregation. Must not be empty.
34 | * @param size The max size of the Top K aggregation. Can be null.
35 | * @param threshold The minimum threshold of the Top K aggregation. Can be null.
36 | * @param name The name of the count field.
37 | */
38 | public TopK(Map fieldsToNames, Integer size, Long threshold, String name) {
39 | super(size, AggregationType.TOP_K);
40 | Utilities.requireNonNull(fieldsToNames);
41 | if (fieldsToNames.isEmpty()) {
42 | throw TOP_K_REQUIRES_FIELDS;
43 | }
44 | this.fieldsToNames = fieldsToNames;
45 | this.threshold = threshold;
46 | this.name = Objects.requireNonNull(name);
47 | }
48 |
49 | @Override
50 | public Strategy getStrategy(BulletConfig config) {
51 | return new FrequentItemsSketchingStrategy(this, config);
52 | }
53 |
54 | @Override
55 | public List getFields() {
56 | return new ArrayList<>(fieldsToNames.keySet());
57 | }
58 |
59 | @Override
60 | public String toString() {
61 | return "{size: " + size + ", type: " + type + ", fieldsToNames: " + fieldsToNames + ", threshold: " + threshold + ", name: " + getName() + "}";
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/expressions/BinaryExpression.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.expressions;
7 |
8 | import com.yahoo.bullet.common.BulletException;
9 | import com.yahoo.bullet.querying.evaluators.BinaryEvaluator;
10 | import com.yahoo.bullet.querying.evaluators.Evaluator;
11 | import lombok.Getter;
12 |
13 | import java.util.Objects;
14 |
15 | import static com.yahoo.bullet.query.expressions.Operation.BINARY_OPERATIONS;
16 |
17 | /**
18 | * An expression that requires two operands and a binary operation.
19 | */
20 | @Getter
21 | public class BinaryExpression extends Expression {
22 | private static final long serialVersionUID = -7911485746578844403L;
23 | private static final BulletException BINARY_EXPRESSION_REQUIRES_BINARY_OPERATION =
24 | new BulletException("Binary expression requires a binary operation.", "Please specify a binary operation.");
25 |
26 | private final Expression left;
27 | private final Expression right;
28 | private final Operation op;
29 |
30 | /**
31 | * Constructor that creates a binary expression.
32 | *
33 | * @param left The non-null left operand.
34 | * @param right The non-null right operand.
35 | * @param op The non-null binary operation.
36 | */
37 | public BinaryExpression(Expression left, Expression right, Operation op) {
38 | this.left = Objects.requireNonNull(left);
39 | this.right = Objects.requireNonNull(right);
40 | this.op = Objects.requireNonNull(op);
41 | if (!BINARY_OPERATIONS.contains(op)) {
42 | throw BINARY_EXPRESSION_REQUIRES_BINARY_OPERATION;
43 | }
44 | }
45 |
46 | @Override
47 | public Evaluator getEvaluator() {
48 | return new BinaryEvaluator(this);
49 | }
50 |
51 | @Override
52 | public boolean equals(Object obj) {
53 | if (obj == this) {
54 | return true;
55 | }
56 | if (!(obj instanceof BinaryExpression)) {
57 | return false;
58 | }
59 | BinaryExpression other = (BinaryExpression) obj;
60 | return Objects.equals(left, other.left) &&
61 | Objects.equals(right, other.right) &&
62 | op == other.op &&
63 | type == other.type;
64 | }
65 |
66 | @Override
67 | public int hashCode() {
68 | return Objects.hash(left, right, op, type);
69 | }
70 |
71 | @Override
72 | public String toString() {
73 | return "{left: " + left + ", right: " + right + ", op: " + op + ", " + super.toString() + "}";
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/expressions/CastExpression.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.expressions;
7 |
8 | import com.yahoo.bullet.common.BulletException;
9 | import com.yahoo.bullet.querying.evaluators.CastEvaluator;
10 | import com.yahoo.bullet.querying.evaluators.Evaluator;
11 | import com.yahoo.bullet.typesystem.Type;
12 | import lombok.Getter;
13 |
14 | import java.util.Objects;
15 |
16 | /**
17 | * An expression that requires a value and a cast type.
18 | */
19 | @Getter
20 | public class CastExpression extends Expression {
21 | private static final long serialVersionUID = -1732511101513444236L;
22 | private static final BulletException CAST_EXPRESSION_REQUIRES_VALID_TYPE =
23 | new BulletException("Cast type cannot be null or unknown.", "Please specify a valid cast type.");
24 |
25 | private final Expression value;
26 | private final Type castType;
27 |
28 | /**
29 | * Constructor that creates a cast expression.
30 | *
31 | * @param value The non-null value to cast.
32 | * @param castType The non-null cast type to cast the value to.
33 | */
34 | public CastExpression(Expression value, Type castType) {
35 | this.value = Objects.requireNonNull(value);
36 | this.castType = Objects.requireNonNull(castType);
37 | if (Type.isNull(castType) || Type.isUnknown(castType)) {
38 | throw CAST_EXPRESSION_REQUIRES_VALID_TYPE;
39 | }
40 | }
41 |
42 | @Override
43 | public Evaluator getEvaluator() {
44 | return new CastEvaluator(this);
45 | }
46 |
47 | @Override
48 | public boolean equals(Object obj) {
49 | if (obj == this) {
50 | return true;
51 | }
52 | if (!(obj instanceof CastExpression)) {
53 | return false;
54 | }
55 | CastExpression other = (CastExpression) obj;
56 | return Objects.equals(value, other.value) && castType == other.castType && type == other.type;
57 | }
58 |
59 | @Override
60 | public int hashCode() {
61 | return Objects.hash(value, castType, type);
62 | }
63 |
64 | @Override
65 | public String toString() {
66 | return "{value: " + value + ", castType: " + castType + ", " + super.toString() + "}";
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/expressions/Expression.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.expressions;
7 |
8 | import com.yahoo.bullet.querying.evaluators.Evaluator;
9 | import com.yahoo.bullet.typesystem.Type;
10 | import lombok.Getter;
11 | import lombok.Setter;
12 |
13 | import java.io.Serializable;
14 |
15 | /**
16 | * Expressions are used in Bullet queries to filter on, project, and compute potentially complex values based on
17 | * Bullet record fields.
18 | *
19 | * The supported expressions are:
20 | * - ValueExpression
21 | * - FieldExpression
22 | * - UnaryExpression
23 | * - BinaryExpression
24 | * - NAryExpression
25 | * - ListExpression
26 | * - CastExpression
27 | *
28 | * Look at {@link Evaluator} to see how expressions are evaluated.
29 | */
30 | @Getter @Setter
31 | public abstract class Expression implements Serializable {
32 | private static final long serialVersionUID = -769774785327135375L;
33 |
34 | protected Type type;
35 |
36 | /**
37 | * Gets a new instance of an evaluator for this expression.
38 | *
39 | * @return A newly-constructed evaluator for this expression.
40 | */
41 | public abstract Evaluator getEvaluator();
42 |
43 | @Override
44 | public abstract boolean equals(Object obj);
45 |
46 | @Override
47 | public abstract int hashCode();
48 |
49 | @Override
50 | public String toString() {
51 | return "type: " + type;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/expressions/ListExpression.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.expressions;
7 |
8 | import com.yahoo.bullet.common.Utilities;
9 | import com.yahoo.bullet.querying.evaluators.Evaluator;
10 | import com.yahoo.bullet.querying.evaluators.ListEvaluator;
11 | import lombok.Getter;
12 |
13 | import java.util.List;
14 | import java.util.Objects;
15 |
16 | /**
17 | * An expression that holds a list of expressions.
18 | */
19 | @Getter
20 | public class ListExpression extends Expression {
21 | private static final long serialVersionUID = 311789452858823415L;
22 |
23 | private final List values;
24 |
25 | /**
26 | * Constructor that creates a list expression.
27 | *
28 | * @param values The non-null list of values to be wrapped.
29 | */
30 | public ListExpression(List values) {
31 | this.values = Utilities.requireNonNull(values);
32 | }
33 |
34 | @Override
35 | public Evaluator getEvaluator() {
36 | return new ListEvaluator(this);
37 | }
38 |
39 | @Override
40 | public boolean equals(Object obj) {
41 | if (obj == this) {
42 | return true;
43 | }
44 | if (!(obj instanceof ListExpression)) {
45 | return false;
46 | }
47 | ListExpression other = (ListExpression) obj;
48 | return Objects.equals(values, other.values) && type == other.type;
49 | }
50 |
51 | @Override
52 | public int hashCode() {
53 | return Objects.hash(values, type);
54 | }
55 |
56 | @Override
57 | public String toString() {
58 | return "{values: " + values + ", " + super.toString() + "}";
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/expressions/NAryExpression.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.expressions;
7 |
8 | import com.yahoo.bullet.common.BulletException;
9 | import com.yahoo.bullet.common.Utilities;
10 | import com.yahoo.bullet.querying.evaluators.Evaluator;
11 | import com.yahoo.bullet.querying.evaluators.NAryEvaluator;
12 | import lombok.Getter;
13 |
14 | import java.util.List;
15 | import java.util.Objects;
16 |
17 | import static com.yahoo.bullet.query.expressions.Operation.N_ARY_OPERATIONS;
18 |
19 | /**
20 | * An expression that requires a list of operands and an n-ary operation.
21 | */
22 | @Getter
23 | public class NAryExpression extends Expression {
24 | private static final long serialVersionUID = -1000391436451418013L;
25 | private static final BulletException N_ARY_EXPRESSION_REQUIRES_N_ARY_OPERATION =
26 | new BulletException("N-ary expression requires an n-ary operation.", "Please specify an n-ary operation.");
27 | private static final String DELIMITER = ", ";
28 |
29 | private final List operands;
30 | private final Operation op;
31 |
32 | /**
33 | * Constructor that creates an n-ary expression.
34 | *
35 | * @param operands The non-null list of operands.
36 | * @param op The non-null n-ary operation.
37 | */
38 | public NAryExpression(List operands, Operation op) {
39 | this.operands = Utilities.requireNonNull(operands);
40 | this.op = Objects.requireNonNull(op);
41 | if (!N_ARY_OPERATIONS.contains(op)) {
42 | throw N_ARY_EXPRESSION_REQUIRES_N_ARY_OPERATION;
43 | }
44 | }
45 |
46 | @Override
47 | public Evaluator getEvaluator() {
48 | return new NAryEvaluator(this);
49 | }
50 |
51 | @Override
52 | public boolean equals(Object obj) {
53 | if (obj == this) {
54 | return true;
55 | }
56 | if (!(obj instanceof NAryExpression)) {
57 | return false;
58 | }
59 | NAryExpression other = (NAryExpression) obj;
60 | return Objects.equals(operands, other.operands) && op == other.op && type == other.type;
61 | }
62 |
63 | @Override
64 | public int hashCode() {
65 | return Objects.hash(operands, op, type);
66 | }
67 |
68 | @Override
69 | public String toString() {
70 | return "{operands: " + operands + ", op: " + op + ", " + super.toString() + "}";
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/expressions/UnaryExpression.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.expressions;
7 |
8 | import com.yahoo.bullet.common.BulletException;
9 | import com.yahoo.bullet.querying.evaluators.Evaluator;
10 | import com.yahoo.bullet.querying.evaluators.UnaryEvaluator;
11 | import lombok.Getter;
12 |
13 | import java.util.Objects;
14 |
15 | import static com.yahoo.bullet.query.expressions.Operation.UNARY_OPERATIONS;
16 |
17 | /**
18 | * An expression that requires an operand and a unary operation.
19 | */
20 | @Getter
21 | public class UnaryExpression extends Expression {
22 | private static final long serialVersionUID = -1893522779659725928L;
23 | private static final BulletException UNARY_EXPRESSION_REQUIRES_UNARY_OPERATION =
24 | new BulletException("Unary expression requires a unary operation.", "Please specify a unary operation.");
25 |
26 | private final Expression operand;
27 | private final Operation op;
28 |
29 | /**
30 | * Constructor that creates a unary expression.
31 | *
32 | * @param operand The non-null operand.
33 | * @param op The non-null unary operation.
34 | */
35 | public UnaryExpression(Expression operand, Operation op) {
36 | this.operand = Objects.requireNonNull(operand);
37 | this.op = Objects.requireNonNull(op);
38 | if (!UNARY_OPERATIONS.contains(op)) {
39 | throw UNARY_EXPRESSION_REQUIRES_UNARY_OPERATION;
40 | }
41 | }
42 |
43 | @Override
44 | public Evaluator getEvaluator() {
45 | return new UnaryEvaluator(this);
46 | }
47 |
48 | @Override
49 | public boolean equals(Object obj) {
50 | if (obj == this) {
51 | return true;
52 | }
53 | if (!(obj instanceof UnaryExpression)) {
54 | return false;
55 | }
56 | UnaryExpression other = (UnaryExpression) obj;
57 | return Objects.equals(operand, other.operand) && op == other.op && type == other.type;
58 | }
59 |
60 | @Override
61 | public int hashCode() {
62 | return Objects.hash(operand, op, type);
63 | }
64 |
65 | @Override
66 | public String toString() {
67 | return "{operand: " + operand + ", op: " + op + ", " + super.toString() + "}";
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/expressions/ValueExpression.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.expressions;
7 |
8 | import com.yahoo.bullet.common.BulletException;
9 | import com.yahoo.bullet.querying.evaluators.Evaluator;
10 | import com.yahoo.bullet.querying.evaluators.ValueEvaluator;
11 | import com.yahoo.bullet.typesystem.Type;
12 | import lombok.Getter;
13 |
14 | import java.io.Serializable;
15 | import java.util.Objects;
16 |
17 | /**
18 | * An expression that requires a primitive or null value.
19 | */
20 | @Getter
21 | public class ValueExpression extends Expression {
22 | private static final long serialVersionUID = -6979831483897873098L;
23 | private static final BulletException VALUE_EXPRESSION_REQUIRES_PRIMITIVE_OR_NULL =
24 | new BulletException("Value must be primitive or null.", "Please specify a valid value.");
25 | private static final String SINGLE_QUOTE = "'";
26 |
27 | private final Serializable value;
28 |
29 | /**
30 | * Constructor that creates a value expression.
31 | *
32 | * @param value The non-null value to be wrapped.
33 | */
34 | public ValueExpression(Serializable value) {
35 | this.value = value;
36 | this.type = Type.getType(value);
37 | if (!Type.isPrimitive(type) && !Type.isNull(type)) {
38 | throw VALUE_EXPRESSION_REQUIRES_PRIMITIVE_OR_NULL;
39 | }
40 | }
41 |
42 | @Override
43 | public Evaluator getEvaluator() {
44 | return new ValueEvaluator(this);
45 | }
46 |
47 | @Override
48 | public boolean equals(Object obj) {
49 | if (obj == this) {
50 | return true;
51 | }
52 | if (!(obj instanceof ValueExpression)) {
53 | return false;
54 | }
55 | ValueExpression other = (ValueExpression) obj;
56 | return Objects.equals(value, other.value) && type == other.type;
57 | }
58 |
59 | @Override
60 | public int hashCode() {
61 | return Objects.hash(value, type);
62 | }
63 |
64 | private String toFormattedString() {
65 | String asString = Objects.toString(value);
66 | return type == Type.STRING ? SINGLE_QUOTE + asString + SINGLE_QUOTE : asString;
67 | }
68 |
69 | @Override
70 | public String toString() {
71 | return "{value: " + toFormattedString() + ", " + super.toString() + "}";
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/postaggregations/Computation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.postaggregations;
7 |
8 | import com.yahoo.bullet.common.BulletException;
9 | import com.yahoo.bullet.common.Utilities;
10 | import com.yahoo.bullet.querying.postaggregations.ComputationStrategy;
11 | import com.yahoo.bullet.querying.postaggregations.PostStrategy;
12 | import com.yahoo.bullet.query.Field;
13 | import lombok.Getter;
14 |
15 | import java.util.List;
16 |
17 | @Getter
18 | public class Computation extends PostAggregation {
19 | private static final long serialVersionUID = -1401910210528780976L;
20 |
21 | public static final BulletException COMPUTATION_REQUIRES_FIELDS =
22 | new BulletException("The COMPUTATION post-aggregation requires at least one field.", "Please add at least one field.");
23 |
24 | private List fields;
25 |
26 | /**
27 | * Constructor that creates a Computation post-aggregation.
28 | *
29 | * @param fields The non-null list of fields to compute after aggregation.
30 | */
31 | public Computation(List fields) {
32 | super(PostAggregationType.COMPUTATION);
33 | Utilities.requireNonNull(fields);
34 | if (fields.isEmpty()) {
35 | throw COMPUTATION_REQUIRES_FIELDS;
36 | }
37 | this.fields = fields;
38 | }
39 |
40 | @Override
41 | public PostStrategy getPostStrategy() {
42 | return new ComputationStrategy(this);
43 | }
44 |
45 | @Override
46 | public String toString() {
47 | return "{type: " + type + ", fields: " + fields + "}";
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/postaggregations/Culling.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.postaggregations;
7 |
8 | import com.yahoo.bullet.common.BulletException;
9 | import com.yahoo.bullet.common.Utilities;
10 | import com.yahoo.bullet.querying.postaggregations.CullingStrategy;
11 | import com.yahoo.bullet.querying.postaggregations.PostStrategy;
12 | import lombok.Getter;
13 |
14 | import java.util.Set;
15 |
16 | @Getter
17 | public class Culling extends PostAggregation {
18 | private static final long serialVersionUID = -4606818164037391850L;
19 |
20 | public static final BulletException CULLING_REQUIRES_FIELDS =
21 | new BulletException("The CULLING post-aggregation requires at least one field.", "Please add at least one field.");
22 |
23 | private Set transientFields;
24 |
25 | /**
26 | * Constructor that creates a Culling post-aggregation.
27 | *
28 | * @param transientFields The non-null set of fields to remove after aggregation.
29 | */
30 | public Culling(Set transientFields) {
31 | super(PostAggregationType.CULLING);
32 | Utilities.requireNonNull(transientFields);
33 | if (transientFields.isEmpty()) {
34 | throw CULLING_REQUIRES_FIELDS;
35 | }
36 | this.transientFields = transientFields;
37 | }
38 |
39 | @Override
40 | public PostStrategy getPostStrategy() {
41 | return new CullingStrategy(this);
42 | }
43 |
44 | @Override
45 | public String toString() {
46 | return "{type: " + type + ", transientFields: " + transientFields + "}";
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/postaggregations/Having.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.postaggregations;
7 |
8 | import com.yahoo.bullet.common.BulletException;
9 | import com.yahoo.bullet.querying.postaggregations.HavingStrategy;
10 | import com.yahoo.bullet.querying.postaggregations.PostStrategy;
11 | import com.yahoo.bullet.query.expressions.Expression;
12 | import lombok.Getter;
13 |
14 | @Getter
15 | public class Having extends PostAggregation {
16 | private static final long serialVersionUID = -123184459098221770L;
17 |
18 | public static final BulletException HAVING_REQUIRES_EXPRESSION =
19 | new BulletException("The HAVING post-aggregation requires an expression.", "Please add an expression.");
20 |
21 | private Expression expression;
22 |
23 | /**
24 | * Constructor that creates a Having post-aggregation.
25 | *
26 | * @param expression The non-null expression to filter by after aggregation.
27 | */
28 | public Having(Expression expression) {
29 | super(PostAggregationType.HAVING);
30 | if (expression == null) {
31 | throw HAVING_REQUIRES_EXPRESSION;
32 | }
33 | this.expression = expression;
34 | }
35 |
36 | @Override
37 | public PostStrategy getPostStrategy() {
38 | return new HavingStrategy(this);
39 | }
40 |
41 | @Override
42 | public String toString() {
43 | return "{type: " + type + ", expression: " + expression + "}";
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/postaggregations/PostAggregation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.postaggregations;
7 |
8 | import com.yahoo.bullet.querying.postaggregations.PostStrategy;
9 | import lombok.AllArgsConstructor;
10 | import lombok.Getter;
11 |
12 | import java.io.Serializable;
13 |
14 | @Getter @AllArgsConstructor
15 | public abstract class PostAggregation implements Serializable {
16 | private static final long serialVersionUID = -3083946184345104820L;
17 |
18 | protected final PostAggregationType type;
19 |
20 | /**
21 | * Returns a new {@link PostStrategy} that handles this post-aggregation.
22 |
23 | * @return A new instance of a strategy that handles this post-aggregation.
24 | */
25 | public abstract PostStrategy getPostStrategy();
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/postaggregations/PostAggregationType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.postaggregations;
7 |
8 | /**
9 | * Represents the type of the {@link PostAggregation}.
10 | */
11 | public enum PostAggregationType {
12 | HAVING,
13 | COMPUTATION,
14 | ORDER_BY,
15 | CULLING;
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/tablefunctions/Explode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.tablefunctions;
7 |
8 | import com.yahoo.bullet.query.expressions.Expression;
9 | import com.yahoo.bullet.querying.tablefunctors.ExplodeFunctor;
10 | import com.yahoo.bullet.querying.tablefunctors.TableFunctor;
11 | import lombok.Getter;
12 |
13 | import java.util.Objects;
14 |
15 | /**
16 | * A table function that requires either a list operand and a key alias or a map operand and both key and value aliases.
17 | */
18 | @Getter
19 | public class Explode extends OuterableTableFunction {
20 | private static final long serialVersionUID = 6058738006416405818L;
21 |
22 | private final Expression field;
23 | private final String keyAlias;
24 | private final String valueAlias;
25 |
26 | /**
27 | * Constructor that creates an EXPLODE table function.
28 | *
29 | * @param field The non-null field to explode.
30 | * @param keyAlias The non-null alias for the key column of the exploded field.
31 | * @param valueAlias The alias for the value column of the exploded field.
32 | * @param outer The outer option.
33 | */
34 | public Explode(Expression field, String keyAlias, String valueAlias, boolean outer) {
35 | super(outer, TableFunctionType.EXPLODE);
36 | this.field = Objects.requireNonNull(field);
37 | this.keyAlias = Objects.requireNonNull(keyAlias);
38 | this.valueAlias = valueAlias;
39 | }
40 |
41 | @Override
42 | public TableFunctor getTableFunctor() {
43 | return new ExplodeFunctor(this);
44 | }
45 |
46 | @Override
47 | public String toString() {
48 | return "{outer: " + outer + ", type: " + type + ", field: " + field + ", keyAlias: " + keyAlias + ", valueAlias: " + valueAlias + "}";
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/tablefunctions/LateralView.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.tablefunctions;
7 |
8 | import com.yahoo.bullet.querying.tablefunctors.LateralViewFunctor;
9 | import com.yahoo.bullet.querying.tablefunctors.TableFunctor;
10 | import lombok.Getter;
11 |
12 | import java.util.Collections;
13 | import java.util.List;
14 | import java.util.Objects;
15 |
16 | /**
17 | * A table function that requires another table function.
18 | */
19 | @Getter
20 | public class LateralView extends TableFunction {
21 | private static final long serialVersionUID = -8238108616312386350L;
22 |
23 | private final List tableFunctions;
24 |
25 | /**
26 | * Constructor that creates a LATERAL VIEW from a {@link List} of {@link TableFunction}.
27 | *
28 | * @param tableFunctions The non-null list of table functions to chain lateral views.
29 | */
30 | public LateralView(List tableFunctions) {
31 | super(TableFunctionType.LATERAL_VIEW);
32 | this.tableFunctions = Objects.requireNonNull(tableFunctions);
33 | }
34 |
35 | /**
36 | * Constructor that creates a LATERAL VIEW from a {@link TableFunction}.
37 | *
38 | * @param tableFunction The non-null table function to apply a lateral view.
39 | */
40 | public LateralView(TableFunction tableFunction) {
41 | this(Collections.singletonList(Objects.requireNonNull(tableFunction)));
42 | }
43 |
44 | @Override
45 | public TableFunctor getTableFunctor() {
46 | return new LateralViewFunctor(this);
47 | }
48 |
49 | @Override
50 | public String toString() {
51 | return "{type: " + type + ", tableFunctions: " + tableFunctions + "}";
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/tablefunctions/OuterableTableFunction.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.tablefunctions;
7 |
8 | import lombok.Getter;
9 |
10 | /**
11 | * The OuterableTableFunction class adds the outer option. When outer is specified, a table function that generates no
12 | * records from a Bullet record will generate an empty record instead.
13 | */
14 | @Getter
15 | public abstract class OuterableTableFunction extends TableFunction {
16 | private static final long serialVersionUID = 3175147159913255802L;
17 |
18 | protected final boolean outer;
19 |
20 | public OuterableTableFunction(boolean outer, TableFunctionType type) {
21 | super(type);
22 | this.outer = outer;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/tablefunctions/TableFunction.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.tablefunctions;
7 |
8 | import com.yahoo.bullet.querying.tablefunctors.TableFunctor;
9 | import lombok.AllArgsConstructor;
10 | import lombok.Getter;
11 |
12 | import java.io.Serializable;
13 |
14 | /**
15 | * Table functions are used in Bullet queries to generate virtual records from incoming Bullet records. The generated
16 | * records are then fed to the rest of the query (filter, projection, aggregation, etc.)
17 | *
18 | * Currently, the supported table function types are Lateral View and Explode.
19 | *
20 | * Look at {@link TableFunctor} to see how table functions are applied in the {@link com.yahoo.bullet.querying.Querier}.
21 | */
22 | @Getter @AllArgsConstructor
23 | public abstract class TableFunction implements Serializable {
24 | private static final long serialVersionUID = 4126801547249854808L;
25 |
26 | protected final TableFunctionType type;
27 |
28 | /**
29 | * Gets a new instance of a table functor for this table function.
30 | *
31 | * @return A newly-constructed table functor for this table function.
32 | */
33 | public abstract TableFunctor getTableFunctor();
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/query/tablefunctions/TableFunctionType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.query.tablefunctions;
7 |
8 | /**
9 | * Represents the type of the {@link TableFunction}.
10 | */
11 | public enum TableFunctionType {
12 | LATERAL_VIEW,
13 | EXPLODE
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/Filter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying;
7 |
8 | import com.yahoo.bullet.query.expressions.Expression;
9 | import com.yahoo.bullet.querying.evaluators.Evaluator;
10 | import com.yahoo.bullet.record.BulletRecord;
11 | import com.yahoo.bullet.typesystem.Type;
12 | import com.yahoo.bullet.typesystem.TypedObject;
13 |
14 | /**
15 | * Filter consists of an evaluator built from the filter expression in the bullet query.
16 | *
17 | * Note, the filter expression does not necessarily have to have boolean type as it will be force-casted anyways.
18 | * Also note that if the evaluator throws an exception, the filter will not match.
19 | */
20 | public class Filter {
21 | private Evaluator evaluator;
22 |
23 | public Filter(Expression filter) {
24 | evaluator = filter.getEvaluator();
25 | }
26 |
27 | /**
28 | * Checks whether the given record matches this filter.
29 | *
30 | * @param record The BulletRecord to check.
31 | * @return True if the record matches this filter and false otherwise.
32 | */
33 | public boolean match(BulletRecord record) {
34 | try {
35 | TypedObject value = evaluator.evaluate(record);
36 | return !value.isNull() && (Boolean) value.forceCast(Type.BOOLEAN).getValue();
37 | } catch (Exception e) {
38 | return false;
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/RateLimitError.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying;
7 |
8 | import com.yahoo.bullet.common.BulletError;
9 | import com.yahoo.bullet.result.Meta;
10 |
11 | import java.util.Arrays;
12 | import java.util.Collections;
13 | import java.util.List;
14 |
15 | public class RateLimitError extends BulletError {
16 | private static final long serialVersionUID = 5056840730518175058L;
17 |
18 | public static final String ERROR_FORMAT = "Exceeded the maximum rate limit for the query: %.2f emits per second. " +
19 | "Current rate: %.2f emits per second";
20 | public static final String NARROW_FILTER = "Try using more filters to reduce the data";
21 | public static final String TIME_WINDOW = "Try using a time based window instead of a record based window";
22 | public static final List RESOLUTIONS = Arrays.asList(NARROW_FILTER, TIME_WINDOW);
23 |
24 | /**
25 | /**
26 | * Creates an instance of this from a given absolute exceeded rate and a maximum rate limit.
27 | *
28 | * @param rate The exceeded rate that caused the error.
29 | * @param limit The maximum rate limit for the query.
30 | */
31 | public RateLimitError(double rate, double limit) {
32 | super(String.format(ERROR_FORMAT, limit * RateLimiter.SECOND, rate * RateLimiter.SECOND), RESOLUTIONS);
33 | }
34 |
35 | /**
36 | * Makes this into a {@link Meta} object.
37 | *
38 | * @return A meta object containing this error.
39 | */
40 | public Meta makeMeta() {
41 | return new Meta().addErrors(Collections.singletonList(this));
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/RunningQuery.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying;
7 |
8 | import com.yahoo.bullet.pubsub.Metadata;
9 | import com.yahoo.bullet.query.Query;
10 | import lombok.Getter;
11 |
12 | /**
13 | * A wrapper for a running query.
14 | */
15 | @Getter
16 | public class RunningQuery {
17 | private final String id;
18 | private final Query query;
19 | private final String queryString;
20 | private final long startTime;
21 |
22 | /**
23 | * Constructor that takes an id, query, and metadata that contains the query string and start time.
24 | *
25 | * @param id The query id.
26 | * @param query The query object.
27 | * @param metadata The metadata associated with the given query.
28 | */
29 | public RunningQuery(String id, Query query, Metadata metadata) {
30 | this.id = id;
31 | this.query = query;
32 | this.queryString = (String) metadata.getContent();
33 | this.startTime = metadata.getCreated();
34 | }
35 |
36 | @Override
37 | public String toString() {
38 | return query.toString();
39 | }
40 |
41 | /**
42 | * Returns true if this running query has timed out. In other words, it returns whether this has been running
43 | * longer than the query duration.
44 | *
45 | * @return A boolean denoting whether this query has timed out.
46 | */
47 | public boolean isTimedOut() {
48 | // Never add to query.getDuration() since it can be infinite (Long.MAX_VALUE)
49 | return System.currentTimeMillis() - startTime >= query.getDuration();
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/aggregations/GroupAllStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying.aggregations;
7 |
8 | import com.yahoo.bullet.query.aggregations.Aggregation;
9 | import com.yahoo.bullet.query.aggregations.GroupAll;
10 | import com.yahoo.bullet.querying.aggregations.grouping.GroupData;
11 | import com.yahoo.bullet.querying.aggregations.grouping.GroupOperation;
12 | import com.yahoo.bullet.common.BulletConfig;
13 | import com.yahoo.bullet.common.SerializerDeserializer;
14 | import com.yahoo.bullet.record.BulletRecord;
15 | import com.yahoo.bullet.record.BulletRecordProvider;
16 | import com.yahoo.bullet.result.Clip;
17 | import lombok.extern.slf4j.Slf4j;
18 |
19 | import java.util.ArrayList;
20 | import java.util.List;
21 | import java.util.Set;
22 |
23 | @Slf4j
24 | public class GroupAllStrategy implements Strategy {
25 | // We only have a single group.
26 | private GroupData data;
27 |
28 | private Set operations;
29 | private BulletRecordProvider provider;
30 | /**
31 | * Constructor that requires an {@link Aggregation}.
32 | *
33 | * @param aggregation The {@link Aggregation} that specifies how and what this will compute.
34 | * @param config The BulletConfig.
35 | */
36 | public GroupAllStrategy(GroupAll aggregation, BulletConfig config) {
37 | // GroupOperations is all we care about - size etc. are meaningless for Group All since it's a single result
38 | operations = aggregation.getOperations();
39 | data = new GroupData(operations);
40 | this.provider = config.getBulletRecordProvider();
41 | }
42 |
43 | @Override
44 | public void consume(BulletRecord data) {
45 | this.data.consume(data);
46 | }
47 |
48 | @Override
49 | public void combine(byte[] data) {
50 | this.data.combine(data);
51 | }
52 |
53 | @Override
54 | public byte[] getData() {
55 | return SerializerDeserializer.toBytes(data);
56 | }
57 |
58 | @Override
59 | public Clip getResult() {
60 | return Clip.of(getRecords());
61 | }
62 |
63 | @Override
64 | public List getRecords() {
65 | List list = new ArrayList<>();
66 | list.add(data.getMetricsAsBulletRecord(provider));
67 | return list;
68 | }
69 |
70 | @Override
71 | public void reset() {
72 | data = new GroupData(operations);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/aggregations/KMVStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying.aggregations;
7 |
8 | import com.yahoo.bullet.querying.aggregations.sketches.KMVSketch;
9 | import com.yahoo.bullet.common.BulletConfig;
10 | import com.yahoo.bullet.query.aggregations.Aggregation;
11 | import com.yahoo.sketches.ResizeFactor;
12 |
13 | /**
14 | * The parent class for {@link SketchingStrategy} that use the KMV type of Sketch - Theta and Tuple.
15 | */
16 | abstract class KMVStrategy extends SketchingStrategy {
17 | /**
18 | * Constructor that requires an {@link Aggregation} and a {@link BulletConfig} configuration.
19 | *
20 | * @param aggregation An {@link Aggregation} with valid fields and attributes for this aggregation type.
21 | * @param config The config that has relevant configs for this strategy.
22 | */
23 | @SuppressWarnings("unchecked")
24 | KMVStrategy(Aggregation aggregation, BulletConfig config) {
25 | super(aggregation, config);
26 | }
27 |
28 | /**
29 | * Converts a integer representing the resizing for Sketches into a {@link ResizeFactor}.
30 | *
31 | * @param config The config that has relevant configs for this strategy.
32 | * @param key The key to get the configured resize factor from the configuration.
33 | * @return A {@link ResizeFactor} represented by the integer or {@link ResizeFactor#X8} otherwise.
34 | */
35 | @SuppressWarnings("unchecked")
36 | ResizeFactor getResizeFactor(BulletConfig config, String key) {
37 | return getResizeFactor(config.getAs(key, Integer.class));
38 | }
39 | /**
40 | * Converts a integer representing the resizing for Sketches into a {@link ResizeFactor}.
41 | *
42 | * @param factor An int representing the scaling when the Sketch reaches its threshold. Supports 1, 2, 4 and 8.
43 | * @return A {@link ResizeFactor} represented by the integer or {@link ResizeFactor#X8} otherwise.
44 | */
45 | public static ResizeFactor getResizeFactor(int factor) {
46 | switch (factor) {
47 | case 1:
48 | return ResizeFactor.X1;
49 | case 2:
50 | return ResizeFactor.X2;
51 | case 4:
52 | return ResizeFactor.X4;
53 | default:
54 | return ResizeFactor.X8;
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/aggregations/Strategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying.aggregations;
7 |
8 | import com.yahoo.bullet.common.Monoidal;
9 | import com.yahoo.bullet.result.Meta;
10 |
11 | public interface Strategy extends Monoidal {
12 | /**
13 | * Returns false if more data should not be consumed or combined. This method can be used to avoid passing more
14 | * data into this Strategy. By default, returns false unless overridden.
15 | *
16 | * @return A boolean denoting whether the next consumption or combination should not occur.
17 | */
18 | @Override
19 | default boolean isClosed() {
20 | return false;
21 | }
22 |
23 | /**
24 | * Get the {@link Meta} so far. By default, returns an empty one.
25 | *
26 | * @return The resulting metadata of the data aggregated so far.
27 | */
28 | @Override
29 | default Meta getMetadata() {
30 | return new Meta();
31 | }
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/aggregations/grouping/GroupDataSummaryFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying.aggregations.grouping;
7 |
8 | import com.yahoo.memory.Memory;
9 | import com.yahoo.sketches.tuple.DeserializeResult;
10 | import com.yahoo.sketches.tuple.Summary;
11 | import com.yahoo.sketches.tuple.SummaryFactory;
12 | import com.yahoo.sketches.tuple.SummarySetOperations;
13 |
14 | public class GroupDataSummaryFactory implements SummaryFactory {
15 | public static final int SERIALIZED_SIZE = 1;
16 | public static final byte[] SERIALIZED = new byte[SERIALIZED_SIZE];
17 | public static final GroupDataSummarySetOperations SUMMARY_OPERATIONS = new GroupDataSummarySetOperations();
18 |
19 | @Override
20 | public Summary newSummary() {
21 | return new GroupDataSummary();
22 | }
23 |
24 | @Override
25 | public SummarySetOperations getSummarySetOperations() {
26 | // Stateless so return the static one
27 | return SUMMARY_OPERATIONS;
28 | }
29 |
30 | @Override
31 | public DeserializeResult summaryFromMemory(Memory serializedSummary) {
32 | return GroupDataSummary.fromMemory(serializedSummary);
33 | }
34 |
35 | @Override
36 | public byte[] toByteArray() {
37 | return SERIALIZED;
38 | }
39 |
40 | /**
41 | * Needed to deserialize an instance of this {@link GroupDataSummaryFactory} from a {@link Memory}.
42 | *
43 | * @param summaryFactory The serialized summary factory.
44 | * @return A {@link DeserializeResult} representing the deserialized summary factory.
45 | */
46 | public static DeserializeResult fromMemory(Memory summaryFactory) {
47 | // This has no state so it does not use the Memory
48 | return new DeserializeResult<>(new GroupDataSummaryFactory(), SERIALIZED_SIZE);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/aggregations/grouping/GroupDataSummarySetOperations.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying.aggregations.grouping;
7 |
8 | import com.yahoo.sketches.tuple.SummarySetOperations;
9 |
10 | /**
11 | * The stateless implementation of the summary set operations for a {@link GroupDataSummary}. Intersection is not
12 | * supported.
13 | */
14 | public class GroupDataSummarySetOperations implements SummarySetOperations {
15 | @Override
16 | public GroupDataSummary union(GroupDataSummary a, GroupDataSummary b) {
17 | return GroupDataSummary.mergeInPlace(a, b);
18 | }
19 |
20 | @Override
21 | public GroupDataSummary intersection(GroupDataSummary a, GroupDataSummary b) {
22 | throw new UnsupportedOperationException("Intersection is not supported at the moment.");
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/evaluators/BinaryEvaluator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying.evaluators;
7 |
8 | import com.yahoo.bullet.query.expressions.BinaryExpression;
9 | import com.yahoo.bullet.record.BulletRecord;
10 | import com.yahoo.bullet.typesystem.TypedObject;
11 |
12 | /**
13 | * An evaluator that applies a binary operator to the result of a left evaluator and the result of a right evaluator.
14 | */
15 | public class BinaryEvaluator extends Evaluator {
16 | private static final long serialVersionUID = -467853226398830498L;
17 |
18 | final Evaluator left;
19 | final Evaluator right;
20 | final BinaryOperations.BinaryOperator op;
21 |
22 | /**
23 | * Constructor that creates a binary evaluator from a {@link BinaryExpression}.
24 | *
25 | * @param binaryExpression The binary expression to construct the evaluator from.
26 | */
27 | public BinaryEvaluator(BinaryExpression binaryExpression) {
28 | left = binaryExpression.getLeft().getEvaluator();
29 | right = binaryExpression.getRight().getEvaluator();
30 | op = BinaryOperations.BINARY_OPERATORS.get(binaryExpression.getOp());
31 | }
32 |
33 | @Override
34 | public TypedObject evaluate(BulletRecord record) {
35 | return op.apply(left, right, record);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/evaluators/CastEvaluator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying.evaluators;
7 |
8 | import com.yahoo.bullet.query.expressions.CastExpression;
9 | import com.yahoo.bullet.record.BulletRecord;
10 | import com.yahoo.bullet.typesystem.Type;
11 | import com.yahoo.bullet.typesystem.TypedObject;
12 |
13 | /**
14 | * An evaluator that force casts the result of an evaluator to a given type.
15 | */
16 | public class CastEvaluator extends Evaluator {
17 | private static final long serialVersionUID = -7527404049388459123L;
18 |
19 | final Evaluator value;
20 | final Type castType;
21 |
22 | /**
23 | * Constructor that creates a cast evaluator from a {@link CastExpression}.
24 | *
25 | * @param castExpression The cast expression to construct the evaluator from.
26 | */
27 | public CastEvaluator(CastExpression castExpression) {
28 | value = castExpression.getValue().getEvaluator();
29 | castType = castExpression.getCastType();
30 | }
31 |
32 | @Override
33 | public TypedObject evaluate(BulletRecord record) {
34 | return value.evaluate(record).forceCast(castType);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/evaluators/Evaluator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying.evaluators;
7 |
8 | import com.yahoo.bullet.record.BulletRecord;
9 | import com.yahoo.bullet.typesystem.TypedObject;
10 |
11 | import java.io.Serializable;
12 |
13 | /**
14 | * Evaluators are built from expressions. They are evaluated given a {@link BulletRecord} and will throw exceptions on
15 | * any errors which are most likely to be the result of missing fields or incorrect types.
16 | */
17 | public abstract class Evaluator implements Serializable {
18 | private static final long serialVersionUID = 8998958368200061680L;
19 |
20 | /**
21 | * Evaluates this evaluator on the given {@link BulletRecord}.
22 | *
23 | * @param record The Bullet record to evaluate this evaluator on.
24 | * @return The result of this evaluator on the given Bullet record.
25 | */
26 | public abstract TypedObject evaluate(BulletRecord record);
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/evaluators/ListEvaluator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying.evaluators;
7 |
8 | import com.yahoo.bullet.query.expressions.Expression;
9 | import com.yahoo.bullet.query.expressions.ListExpression;
10 | import com.yahoo.bullet.record.BulletRecord;
11 | import com.yahoo.bullet.typesystem.TypedObject;
12 |
13 | import java.util.ArrayList;
14 | import java.util.List;
15 | import java.util.stream.Collectors;
16 |
17 | /**
18 | * An evaluator that returns a list of the results of a list of evaluators.
19 | */
20 | public class ListEvaluator extends Evaluator {
21 | private static final long serialVersionUID = -2945310695360542354L;
22 |
23 | final List evaluators;
24 |
25 | /**
26 | * Constructor that creates a list evaluator from a {@link ListExpression}.
27 | *
28 | * @param listExpression The list expression to construct the evaluator from.
29 | */
30 | public ListEvaluator(ListExpression listExpression) {
31 | evaluators = listExpression.getValues().stream().map(Expression::getEvaluator).collect(Collectors.toList());
32 | }
33 |
34 | @Override
35 | public TypedObject evaluate(BulletRecord record) {
36 | return new TypedObject(evaluators.stream().map(e -> e.evaluate(record).getValue()).collect(Collectors.toCollection(ArrayList::new)));
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/evaluators/NAryEvaluator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying.evaluators;
7 |
8 | import com.yahoo.bullet.query.expressions.Expression;
9 | import com.yahoo.bullet.query.expressions.NAryExpression;
10 | import com.yahoo.bullet.record.BulletRecord;
11 | import com.yahoo.bullet.typesystem.TypedObject;
12 |
13 | import java.util.List;
14 | import java.util.stream.Collectors;
15 |
16 | /**
17 | * An evaluator that applies an n-ary operator to the results of a list of evaluators.
18 | */
19 | public class NAryEvaluator extends Evaluator {
20 | private static final long serialVersionUID = 54879052369401372L;
21 |
22 | final List operands;
23 | final NAryOperations.NAryOperator op;
24 |
25 | /**
26 | * Constructor that creates an n-ary evaluator from a {@link NAryExpression}.
27 | *
28 | * @param nAryExpression The n-ary expression to construct the evaluator from.
29 | */
30 | public NAryEvaluator(NAryExpression nAryExpression) {
31 | operands = nAryExpression.getOperands().stream().map(Expression::getEvaluator).collect(Collectors.toList());
32 | op = NAryOperations.N_ARY_OPERATORS.get(nAryExpression.getOp());
33 | }
34 |
35 | @Override
36 | public TypedObject evaluate(BulletRecord record) {
37 | return op.apply(operands, record);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/evaluators/UnaryEvaluator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying.evaluators;
7 |
8 | import com.yahoo.bullet.query.expressions.UnaryExpression;
9 | import com.yahoo.bullet.record.BulletRecord;
10 | import com.yahoo.bullet.typesystem.TypedObject;
11 |
12 | /**
13 | * An evaluator that applies a unary operator to the result of an evaluator.
14 | */
15 | public class UnaryEvaluator extends Evaluator {
16 | private static final long serialVersionUID = -4008832651046022947L;
17 |
18 | final Evaluator operand;
19 | final UnaryOperations.UnaryOperator op;
20 |
21 | /**
22 | * Constructor that creates a unary evaluator from a {@link UnaryExpression}.
23 | *
24 | * @param unaryExpression The unary expression to construct the evaluator from.
25 | */
26 | public UnaryEvaluator(UnaryExpression unaryExpression) {
27 | operand = unaryExpression.getOperand().getEvaluator();
28 | op = UnaryOperations.UNARY_OPERATORS.get(unaryExpression.getOp());
29 | }
30 |
31 | @Override
32 | public TypedObject evaluate(BulletRecord record) {
33 | return op.apply(operand, record);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/evaluators/ValueEvaluator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying.evaluators;
7 |
8 | import com.yahoo.bullet.query.expressions.ValueExpression;
9 | import com.yahoo.bullet.record.BulletRecord;
10 | import com.yahoo.bullet.typesystem.TypedObject;
11 |
12 | /**
13 | * An evaluator that returns a constant value.
14 | */
15 | public class ValueEvaluator extends Evaluator {
16 | private static final long serialVersionUID = -1689526286716310223L;
17 |
18 | final TypedObject value;
19 |
20 | /**
21 | * Constructor that creates a value evaluator from a {@link ValueExpression}.
22 | *
23 | * @param valueExpression The value expression to construct the evaluator from.
24 | */
25 | public ValueEvaluator(ValueExpression valueExpression) {
26 | value = new TypedObject(valueExpression.getType(), valueExpression.getValue());
27 | }
28 |
29 | @Override
30 | public TypedObject evaluate(BulletRecord record) {
31 | return value;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/partitioning/Partitioner.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying.partitioning;
7 |
8 | import com.yahoo.bullet.query.Query;
9 | import com.yahoo.bullet.record.BulletRecord;
10 |
11 | import java.util.Set;
12 |
13 | public interface Partitioner {
14 | /**
15 | * Returns the partitioning keys for this {@link Query} instance.
16 | *
17 | * @param query The query to partition for.
18 | * @return A non-null {@link Set} of Strings representing the keys for this query.
19 | */
20 | Set getKeys(Query query);
21 |
22 | /**
23 | * Returns the partitioning keys for this {@link BulletRecord} instance.
24 | *
25 | * @param record The record to partition.
26 | * @return A non-null {@link Set} of Strings representing the keys for this record.
27 | */
28 | Set getKeys(BulletRecord record);
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/postaggregations/ComputationStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying.postaggregations;
7 |
8 | import com.yahoo.bullet.query.postaggregations.Computation;
9 | import com.yahoo.bullet.querying.Projection;
10 | import com.yahoo.bullet.result.Clip;
11 | import lombok.extern.slf4j.Slf4j;
12 |
13 | @Slf4j
14 | public class ComputationStrategy implements PostStrategy {
15 | private Projection projection;
16 |
17 | /**
18 | * Constructor that creates a Computation post-strategy.
19 | *
20 | * @param computation The computation post-aggregation to create a strategy for.
21 | */
22 | public ComputationStrategy(Computation computation) {
23 | projection = new Projection(computation.getFields());
24 | }
25 |
26 | @Override
27 | public Clip execute(Clip clip) {
28 | clip.getRecords().forEach(projection::project);
29 | return clip;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/postaggregations/CullingStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying.postaggregations;
7 |
8 | import com.yahoo.bullet.query.postaggregations.Culling;
9 | import com.yahoo.bullet.result.Clip;
10 |
11 | import java.util.Set;
12 |
13 | public class CullingStrategy implements PostStrategy {
14 | private Set transientFields;
15 |
16 | /**
17 | * Constructor that creates a Culling post-strategy.
18 | *
19 | * @param culling The culling post-aggregation to create a strategy for.
20 | */
21 | public CullingStrategy(Culling culling) {
22 | transientFields = culling.getTransientFields();
23 | }
24 |
25 | @Override
26 | public Clip execute(Clip clip) {
27 | for (String field : transientFields) {
28 | clip.getRecords().forEach(record -> record.remove(field));
29 | }
30 | return clip;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/postaggregations/HavingStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying.postaggregations;
7 |
8 | import com.yahoo.bullet.query.postaggregations.Having;
9 | import com.yahoo.bullet.querying.evaluators.Evaluator;
10 | import com.yahoo.bullet.result.Clip;
11 | import com.yahoo.bullet.typesystem.Type;
12 |
13 | public class HavingStrategy implements PostStrategy {
14 | private final Evaluator evaluator;
15 |
16 | /**
17 | * Constructor that creates a Having post-strategy.
18 | *
19 | * @param having The Having post-aggregation to create a strategy for.
20 | */
21 | public HavingStrategy(Having having) {
22 | evaluator = having.getExpression().getEvaluator();
23 | }
24 |
25 | @Override
26 | public Clip execute(Clip clip) {
27 | clip.getRecords().removeIf(record -> {
28 | try {
29 | return !((Boolean) evaluator.evaluate(record).forceCast(Type.BOOLEAN).getValue());
30 | } catch (Exception ignored) {
31 | return true;
32 | }
33 | });
34 | return clip;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/postaggregations/PostStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying.postaggregations;
7 |
8 | import com.yahoo.bullet.result.Clip;
9 |
10 | public interface PostStrategy {
11 | /**
12 | * Executes the post aggregation.
13 | *
14 | * @param clip The input {@link Clip}.
15 | * @return The output {@link Clip}.
16 | */
17 | Clip execute(Clip clip);
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/tablefunctors/LateralViewFunctor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying.tablefunctors;
7 |
8 | import com.yahoo.bullet.query.tablefunctions.LateralView;
9 | import com.yahoo.bullet.query.tablefunctions.TableFunction;
10 | import com.yahoo.bullet.record.BulletRecord;
11 | import com.yahoo.bullet.record.BulletRecordProvider;
12 |
13 | import java.util.List;
14 | import java.util.stream.Collectors;
15 | import java.util.stream.Stream;
16 |
17 | /**
18 | * A table functor that joins the generated records of the nested table functor with the original input record.
19 | */
20 | public class LateralViewFunctor extends TableFunctor {
21 | private static final long serialVersionUID = 1017033253024183470L;
22 |
23 | final List tableFunctors;
24 |
25 | /**
26 | * Constructor that creates a lateral view table functor from a {@link LateralView}.
27 | *
28 | * @param lateralView The lateral view table function to construct the table functor from.
29 | */
30 | public LateralViewFunctor(LateralView lateralView) {
31 | tableFunctors = lateralView.getTableFunctions().stream().map(TableFunction::getTableFunctor).collect(Collectors.toList());
32 | }
33 |
34 | @Override
35 | public List apply(BulletRecord record, BulletRecordProvider provider) {
36 | if (tableFunctors.size() == 1) {
37 | return apply(record, provider, tableFunctors.get(0));
38 | }
39 | Stream recordsStream = Stream.of(record);
40 | for (TableFunctor tableFunctor : tableFunctors) {
41 | recordsStream = recordsStream.flatMap(r -> apply(r, provider, tableFunctor).stream());
42 | }
43 | return recordsStream.collect(Collectors.toList());
44 | }
45 |
46 | private List apply(BulletRecord record, BulletRecordProvider provider, TableFunctor tableFunctor) {
47 | List records = tableFunctor.apply(record, provider);
48 | return records.stream().map(generated -> new LateralViewBulletRecord(record, generated)).collect(Collectors.toList());
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/tablefunctors/OuterableTableFunctor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying.tablefunctors;
7 |
8 | import com.yahoo.bullet.record.BulletRecord;
9 | import com.yahoo.bullet.record.BulletRecordProvider;
10 | import lombok.AllArgsConstructor;
11 |
12 | import java.util.Collections;
13 | import java.util.List;
14 |
15 | /**
16 | * The OuterableTableFunctor class adds an outer option. When outer is specified and no records are generated, an empty
17 | * record will be generated.
18 | *
19 | * Classes inheriting from this class must implement {@link OuterableTableFunctor#outerableApply(BulletRecord, BulletRecordProvider)}
20 | * and not {@link TableFunctor#apply(BulletRecord, BulletRecordProvider)}.
21 | */
22 | @AllArgsConstructor
23 | public abstract class OuterableTableFunctor extends TableFunctor {
24 | private static final long serialVersionUID = 5523194920317863876L;
25 |
26 | protected final boolean outer;
27 |
28 | @Override
29 | public List apply(BulletRecord record, BulletRecordProvider provider) {
30 | List records = outerableApply(record, provider);
31 | if (records.isEmpty() && outer) {
32 | return Collections.singletonList(provider.getInstance());
33 | }
34 | return records;
35 | }
36 |
37 | /**
38 | * Applies this table functor to the given {@link BulletRecord}. This method is called by the main
39 | * {@link #apply(BulletRecord, BulletRecordProvider)} method which will handle the outer option.
40 | *
41 | * @param record The Bullet record to apply this table functor to.
42 | * @param provider The provider used in generating new Bullet records.
43 | * @return The generated list of records from applying this table functor to the given Bullet record.
44 | */
45 | protected abstract List outerableApply(BulletRecord record, BulletRecordProvider provider);
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/querying/tablefunctors/TableFunctor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.querying.tablefunctors;
7 |
8 | import com.yahoo.bullet.record.BulletRecord;
9 | import com.yahoo.bullet.record.BulletRecordProvider;
10 | import lombok.AllArgsConstructor;
11 |
12 | import java.io.Serializable;
13 | import java.util.List;
14 |
15 | /**
16 | * Table functors are built from table functions. A table functor is applied to a {@link BulletRecord} and generates a
17 | * list of {@link BulletRecord}.
18 | *
19 | * Classes inheriting from this class must implement {@link TableFunctor#apply(BulletRecord, BulletRecordProvider)}.
20 | */
21 | @AllArgsConstructor
22 | public abstract class TableFunctor implements Serializable {
23 | private static final long serialVersionUID = 5843896863161739195L;
24 |
25 | /**
26 | * Applies this table functor to the given {@link BulletRecord}.
27 | *
28 | * @param record The Bullet record to apply this table functor to.
29 | * @param provider The provider used in generating new Bullet records.
30 | * @return The generated list of records from applying this table functor to the given Bullet record.
31 | */
32 | public abstract List apply(BulletRecord record, BulletRecordProvider provider);
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/result/JSONFormatter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.result;
7 |
8 | import com.google.gson.Gson;
9 | import com.google.gson.GsonBuilder;
10 | import com.google.gson.JsonPrimitive;
11 | import com.google.gson.JsonSerializer;
12 |
13 | public interface JSONFormatter {
14 | JsonSerializer INVALID_DOUBLES = (item, type, context) -> item.isNaN() || item.isInfinite() ?
15 | new JsonPrimitive(item.toString()) : new JsonPrimitive(item);
16 | Gson GSON = new GsonBuilder().serializeNulls().registerTypeAdapter(Double.class, INVALID_DOUBLES).create();
17 |
18 | /**
19 | * Returns a JSON string representation of object.
20 | * @param object The object to make a JSON out of.
21 | * @return JSON string of the object.
22 | */
23 | static String asJSON(Object object) {
24 | return GSON.toJson(object);
25 | }
26 |
27 | /**
28 | * Returns a deserialized object from JSON using {@link JSONFormatter#GSON}.
29 | *
30 | * @param json The String json that represents the object.
31 | * @param clazz The class of the object.
32 | * @param The type of the object. It must implement {@link JSONFormatter}.
33 | * @return An instance of the object deserialized from JSON.
34 | */
35 | static T fromJSON(String json, Class clazz) {
36 | return GSON.fromJson(json, clazz);
37 | }
38 |
39 | /**
40 | * Convert this object to a JSON string.
41 | * @return The JSON representation of this.
42 | */
43 | String asJSON();
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/com/yahoo/bullet/storage/MemoryStorageManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, Yahoo Inc.
3 | * Licensed under the terms of the Apache License, Version 2.0.
4 | * See the LICENSE file associated with the project for terms.
5 | */
6 | package com.yahoo.bullet.storage;
7 |
8 | import com.yahoo.bullet.common.BulletConfig;
9 |
10 | import java.io.Serializable;
11 | import java.util.HashMap;
12 | import java.util.Map;
13 | import java.util.Set;
14 | import java.util.concurrent.CompletableFuture;
15 |
16 | /**
17 | * A Storage manager that stores everything in-memory and does not support namespaces or partitions.
18 | */
19 | public class MemoryStorageManager extends StorageManager implements Serializable {
20 | private static final long serialVersionUID = 3815534537510449363L;
21 |
22 | private Map storage;
23 |
24 | /**
25 | * Constructor.
26 | *
27 | * @param config The {@link BulletConfig} to create this manager with.
28 | */
29 | public MemoryStorageManager(BulletConfig config) {
30 | super(config);
31 | storage = new HashMap<>();
32 | }
33 |
34 | @Override
35 | protected CompletableFuture putRaw(String namespace, String id, byte[] value) {
36 | storage.put(id, value);
37 | return SUCCESS;
38 | }
39 |
40 | @Override
41 | protected CompletableFuture getRaw(String namespace, String id) {
42 | return CompletableFuture.completedFuture(storage.get(id));
43 | }
44 |
45 | @Override
46 | protected CompletableFuture