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
|
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "field.h"
#include <vespa/document/fieldvalue/fieldvalue.h>
#include <vespa/document/datatype/datatype.h>
#include <vespa/document/fieldset/fieldsets.h>
#include <vespa/vespalib/util/exceptions.h>
#include <vespa/vespalib/stllike/asciistream.h>
#include <vespa/vespalib/util/bobhash.h>
#include <algorithm>
namespace document {
Field::Set::Set(std::vector<CPtr> fields)
: _fields(std::move(fields))
{
std::sort(_fields.begin(), _fields.end(), Field::FieldPtrLess());
_fields.erase(std::unique(_fields.begin(), _fields.end(), Field::FieldPtrEqual()), _fields.end());
}
bool
Field::Set::contains(const Field & field) const {
return std::binary_search(_fields.begin(), _fields.end(), &field, Field::FieldPtrLess());
}
bool
Field::Set::contains(const Set & fields) const {
return std::includes(_fields.begin(), _fields.end(),
fields._fields.begin(), fields._fields.end(),
Field::FieldPtrLess());
}
Field::Field()
: Field("", 0, *DataType::INT)
{ }
Field::Field(vespalib::stringref name, int fieldId, const DataType& dataType)
: FieldSet(),
_name(name),
_dataType(&dataType),
_fieldId(fieldId)
{ }
Field::Field(vespalib::stringref name, const DataType& dataType)
: FieldSet(),
_name(name),
_dataType(&dataType),
_fieldId(calculateIdV7())
{ }
Field::~Field() = default;
FieldValue::UP
Field::createValue() const {
return _dataType->createFieldValue();
}
vespalib::string
Field::toString(bool verbose) const
{
vespalib::asciistream out;
out << "Field(" << getName();
if (verbose) {
out << ", id " << _fieldId;
}
out << ", " << _dataType->toString();
out << ")";
return out.str();
}
bool
Field::contains(const FieldSet& fields) const
{
switch (fields.getType()) {
case Type::FIELD:
return static_cast<const Field&>(fields).getId() == getId();
case Type::SET: {
const auto & set = static_cast<const FieldCollection &>(fields);
return (set.getFields().size() == 1) && ((*set.getFields().begin())->getId() == getId());
}
case Type::NONE:
case Type::DOCID:
return true;
case Type::DOCUMENT_ONLY:
case Type::ALL:
return false;
}
return false;
}
int
Field::calculateIdV7()
{
vespalib::asciistream ost;
ost << getName();
ost << _dataType->getId();
int newId = vespalib::BobHash::hash(ost.str().data(), ost.str().length(), 0);
// Highest bit is reserved to tell 7-bit id's from 31-bit ones
if (newId < 0) newId = -newId;
validateId(newId);
return newId;
}
void
Field::validateId(int newId) {
if (newId >= 100 && newId <= 127) {
throw vespalib::IllegalArgumentException(vespalib::make_string(
"Attempt to set the id of %s to %d failed, values from "
"100 to 127 are reserved for internal use",
getName().data(), newId));
}
if ((uint32_t(newId) & 0x80000000u) != 0) // Highest bit must not be set
{
throw vespalib::IllegalArgumentException(vespalib::make_string(
"Attempt to set the id of %s to %d"
" failed, negative id values are illegal",
getName().data(), newId));
}
}
} // document
|