aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib/src/main/java/com/yahoo/searchlib/aggregation/AggregationResult.java
blob: 3c168090695492cd60ff1c132f650e6dddd702ee (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.searchlib.aggregation;

import com.yahoo.searchlib.expression.ExpressionNode;
import com.yahoo.searchlib.expression.ResultNode;
import com.yahoo.vespa.objects.Deserializer;
import com.yahoo.vespa.objects.ObjectVisitor;
import com.yahoo.vespa.objects.Serializer;

/**
 * The result of some aggregation
 *
 * @author baldersheim
 * @author Simon Thoresen Hult
 */
public abstract class AggregationResult extends ExpressionNode {

    public static final int classId = registerClass(0x4000 + 80, AggregationResult.class);
    private ExpressionNode expression = null;
    private int tag = -1;

    /**
     * Returns the tag of this aggregation result. This is useful for uniquely identifying a result.
     *
     * @return The numerical tag.
     */
    public int getTag() {
        return tag;
    }

    /**
     * Assigns a tag to this group.
     *
     * @param tag the numerical tag to set.
     * @return this, to allow chaining.
     */
    public AggregationResult setTag(int tag) {
        this.tag = tag;
        return this;
    }

    /**
     * Called when merging aggregation results. This method is simply a proxy for the abstract {@link
     * #onMerge(AggregationResult)} method.
     *
     * @param result the result to merge with.
     */
    public void merge(AggregationResult result) {
        onMerge(result);
    }

    /**
     * Hook called when all aggregation results have been merged. This method can be overloaded by
     * subclasses that need special behaviour to occur after merge.
     */
    public void postMerge() {
        // empty
    }

    /** Returns a value that can be used for ranking. */
    public abstract ResultNode getRank();

    /**
     * Sets the expression to aggregate on.
     *
     * @param exp the expression
     * @return this, to allow chaining
     */
    public AggregationResult setExpression(ExpressionNode exp) {
        expression = exp;
        return this;
    }

    /** Returns the expression to aggregate on. */
    public ExpressionNode getExpression() {
        return expression;
    }

    /**
     * Mmust be implemented by subclasses to support merge. It is called as the {@link
     * #merge(AggregationResult)} method is invoked.
     *
     * @param result the result to merge with
     */
    protected abstract void onMerge(AggregationResult result);

    @Override
    public ResultNode getResult() {
        return getRank();
    }

    @Override
    public void onPrepare() {

    }

    @Override
    public boolean onExecute() {
        return true;
    }

    @Override
    protected int onGetClassId() {
        return classId;
    }

    @Override
    protected void onSerialize(Serializer buf) {
        super.onSerialize(buf);
        serializeOptional(buf, expression);
        buf.putInt(null, tag);
    }

    @Override
    protected void onDeserialize(Deserializer buf) {
        super.onDeserialize(buf);
        expression = (ExpressionNode)deserializeOptional(buf);
        tag = buf.getInt(null);
    }

    @Override
    public AggregationResult clone() {
        AggregationResult obj = (AggregationResult)super.clone();
        if (expression != null) {
            obj.expression = expression.clone();
        }
        return obj;
    }

    @Override
    protected final boolean equalsExpression(ExpressionNode obj) {
        AggregationResult rhs = (AggregationResult)obj;
        if (!equals(expression, rhs.expression)) {
            return false;
        }
        if (tag != rhs.tag) {
            return false;
        }
        if (!equalsAggregation(rhs)) {
            return false;
        }
        return true;
    }

    protected abstract boolean equalsAggregation(AggregationResult obj);

    @Override
    public void visitMembers(ObjectVisitor visitor) {
        super.visitMembers(visitor);
        visitor.visit("expression", expression);
        visitor.visit("tag", tag);
    }

}