aboutsummaryrefslogtreecommitdiffstats
path: root/document/src/vespa/document/base/field.h
blob: d576401d2aaeb77affa86db80381a30be6e39957 (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
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
/**
 * \class document::Field
 * \ingroup base
 *
 * \brief Specifies a field within a structured data type.
 *
 * A structured data type contains a key - value mapping of predefined
 * data types. The field class is the key in these maps, and contains
 * an identifier, in addition to datatype of values.
 */
#pragma once

#include <vespa/vespalib/stllike/string.h>
#include <vespa/document/fieldset/fieldset.h>
#include <vector>

namespace document {

class FieldValue;
class DataType;

class Field final : public FieldSet
{
    vespalib::string _name;
    const DataType *_dataType;
    int             _fieldId;
public:
    using CSP = std::shared_ptr<const Field>;
    using SP = std::shared_ptr<Field>;
    using CPtr = const Field *;

    struct FieldPtrLess {
        bool operator()(CPtr f1, CPtr f2) const {
            return (*f1 < *f2);
        }
    };

    struct FieldPtrEqual {
        bool operator()(CPtr f1, CPtr f2) const {
            return (*f1 == *f2);
        }
    };

    class Set {
    public:
        class Builder {
        public:
            Builder & reserve(size_t sz) { _vector.reserve(sz); return *this; }
            Builder & add(CPtr field) { _vector.push_back(field); return *this; }
            Set build() { return Set(std::move(_vector)); }
        private:
            std::vector<CPtr> _vector;
        };
        bool contains(const Field & field) const;
        bool contains(const Set & field) const;
        size_t size() const { return _fields.size(); }
        bool empty() const { return _fields.empty(); }
        const CPtr * begin() const { return _fields.data(); }
        const CPtr * end() const { return begin() + _fields.size(); }
        static Set emptySet() { return Builder().build(); }
    private:
        explicit Set(std::vector<CPtr> fields);
        std::vector<CPtr> _fields;
    };

    /**
     * Creates a completely specified field instance.
     *
     * @param name The name of the field.
     * @param fieldId The numeric ID representing the field.
     * @param type The datatype of the field.
     * @param headerField Whether or not this is a "header" field.
     */
    Field(vespalib::stringref name, int fieldId, const DataType &type);

    Field();

    /**
     * Creates a completely specified field instance. Field ids are generated
     * by hash function.
     *
     * @param name The name of the field.
     * @param dataType The datatype of the field.
     * @param headerField Whether or not this is a "header" field.
     */
    Field(vespalib::stringref name, const DataType &dataType);

    ~Field() override;

    std::unique_ptr<FieldValue> createValue() const;

    // Note that only id is checked for equality.
    bool operator==(const Field & other) const noexcept { return (_fieldId == other._fieldId); }
    bool operator!=(const Field & other) const noexcept { return (_fieldId != other._fieldId); }
    bool operator<(const Field & other) const noexcept { return (_name < other._name); }

    const DataType &getDataType() const { return *_dataType; }

    int getId() const noexcept { return _fieldId; }
    const vespalib::string & getName() const noexcept { return _name; }

    vespalib::string toString(bool verbose=false) const;
    bool contains(const FieldSet& fields) const override;
    Type getType() const override { return Type::FIELD; }
    bool valid() const noexcept { return _fieldId != 0; }
    uint32_t hash() const noexcept { return getId(); }
private:
    int calculateIdV7();

    void validateId(int newId);
};

} // document