aboutsummaryrefslogtreecommitdiffstats
path: root/document/src/main/java/com/yahoo/document/WeightedSetDataType.java
blob: 04ec779bc169f8b9b05c8b9c29bea5576091d155 (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
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.document;

import com.yahoo.document.datatypes.WeightedSet;
import com.yahoo.vespa.objects.Ids;
import com.yahoo.vespa.objects.ObjectVisitor;

/**
 * @author Einar M R Rosenvinge
 */
public class WeightedSetDataType extends CollectionDataType {

    // The global class identifier shared with C++.
    public static int classId = registerClass(Ids.document + 55, WeightedSetDataType.class);

    /** Should an operation to a non-existent member of a weightedset cause the member to be created */
    private boolean createIfNonExistent = false;

    /** Should a member of a weightedset with weight 0 be removed */
    private boolean removeIfZero = false;

    /** The tag type is ambiguous, this flag is true if the user explicitly set a field to tag */
    private boolean tag = false;

    public WeightedSetDataType(DataType nestedType, boolean createIfNonExistent, boolean removeIfZero) {
        this(nestedType, createIfNonExistent, removeIfZero, 0);
    }

    public WeightedSetDataType(DataType nestedType, boolean createIfNonExistent, boolean removeIfZero, int id) {
        super(createName(nestedType, createIfNonExistent, removeIfZero), id, nestedType);
        this.createIfNonExistent = createIfNonExistent;
        this.removeIfZero = removeIfZero;
        if (id == 0) {
            if ((nestedType == STRING) && createIfNonExistent && removeIfZero) { // the tag type definition
                setId(TAG_ID);
            } else {
                setId(getName().toLowerCase().hashCode());
            }
        }
        int code = getId();
        if ((code >= 0) && (code <= DataType.lastPredefinedDataTypeId()) && (code != TAG_ID)) {
            throw new IllegalArgumentException("Cannot create a weighted set datatype with code " + code);
        }
    }

    @Override
    public WeightedSetDataType clone() {
        return (WeightedSetDataType) super.clone();
    }

    /**
     * Called by SD parser if a data type is explicitly tag.
     * 
     * @param tag true if this is a tag set.
     */
    public void setTag(boolean tag) {
        this.tag = tag;
    }

    /**
     * Returns whether or not this is a <em>tag</em> type weighted set.
     * 
     * @return true if this is a tag set.
     */
    public boolean isTag() {
        return tag;
    }

    static private String createName(DataType nested, boolean createIfNonExistent, boolean removeIfZero) {
        if (nested == DataType.STRING && createIfNonExistent && removeIfZero) {
            return "tag";
        } else {
            String name = "WeightedSet<" + nested.getName() + ">";
            if (createIfNonExistent) name += ";Add";
            if (removeIfZero) name += ";Remove";
            return name;
        }
    }

    @Override
    public WeightedSet createFieldValue() {
        return new WeightedSet(this);
    }

    @Override
    public Class getValueClass() {
        return WeightedSet.class;
    }

    /**
     * Returns true if this has the property createIfNonExistent (only relevant for weighted sets)
     *
     * @return createIfNonExistent property
     */
    public boolean createIfNonExistent() {
        return createIfNonExistent;
    }

    /**
     * Returns true if this has the property removeIfZero (only relevant for weighted sets)
     *
     * @return removeIfZero property
     */
    public boolean removeIfZero() {
        return removeIfZero;
    }

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

    @Override
    public FieldPath buildFieldPath(String remainFieldName) {
        return MapDataType.buildFieldPath(remainFieldName, getNestedType(), DataType.INT);
    }

}