summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@oath.com>2018-08-27 10:50:31 +0200
committerHenning Baldersheim <balder@oath.com>2018-08-27 10:50:31 +0200
commit406bb7fca1f90f0ab97f6f6b4752ca3e235c08ce (patch)
treecadff66271030181354170ec0a63667e4ad20bd6
parent4b2f2f0195b4b3c4483d5539b8f50cdd83eb5bf6 (diff)
Only allow query time modification of attributes marked mutable.
-rw-r--r--configdefinitions/src/vespa/attributes.def1
-rw-r--r--searchcommon/src/vespa/searchcommon/attribute/config.cpp21
-rw-r--r--searchcommon/src/vespa/searchcommon/attribute/config.h43
-rw-r--r--searchlib/src/tests/attribute/attribute_operation/attribute_operation_test.cpp12
-rw-r--r--searchlib/src/vespa/searchlib/attribute/attribute_operation.cpp4
5 files changed, 50 insertions, 31 deletions
diff --git a/configdefinitions/src/vespa/attributes.def b/configdefinitions/src/vespa/attributes.def
index 6fea4d95d92..54b25e5b9bd 100644
--- a/configdefinitions/src/vespa/attributes.def
+++ b/configdefinitions/src/vespa/attributes.def
@@ -8,6 +8,7 @@ attribute[].removeifzero bool default=false
attribute[].createifnonexistent bool default=false
attribute[].fastsearch bool default=false
attribute[].huge bool default=false
+attribute[].ismutable bool default=false
attribute[].sortascending bool default=true
attribute[].sortfunction enum { RAW, LOWERCASE, UCA } default=UCA
attribute[].sortstrength enum { PRIMARY, SECONDARY, TERTIARY, QUATERNARY, IDENTICAL } default=PRIMARY
diff --git a/searchcommon/src/vespa/searchcommon/attribute/config.cpp b/searchcommon/src/vespa/searchcommon/attribute/config.cpp
index 221924a1689..ac3d2327157 100644
--- a/searchcommon/src/vespa/searchcommon/attribute/config.cpp
+++ b/searchcommon/src/vespa/searchcommon/attribute/config.cpp
@@ -13,6 +13,7 @@ Config::Config() :
_enableOnlyBitVector(false),
_isFilter(false),
_fastAccess(false),
+ _mutable(false),
_growStrategy(),
_compactionStrategy(),
_predicateParams(),
@@ -29,6 +30,7 @@ Config::Config(BasicType bt, CollectionType ct, bool fastSearch_, bool huge_)
_enableOnlyBitVector(false),
_isFilter(false),
_fastAccess(false),
+ _mutable(false),
_growStrategy(),
_compactionStrategy(),
_predicateParams(),
@@ -40,4 +42,23 @@ Config::Config(const Config &) = default;
Config & Config::operator = (const Config &) = default;
Config::~Config() = default;
+bool
+Config::operator==(const Config &b) const
+{
+ return _basicType == b._basicType &&
+ _type == b._type &&
+ _huge == b._huge &&
+ _fastSearch == b._fastSearch &&
+ _enableBitVectors == b._enableBitVectors &&
+ _enableOnlyBitVector == b._enableOnlyBitVector &&
+ _isFilter == b._isFilter &&
+ _fastAccess == b._fastAccess &&
+ _mutable == b._mutable &&
+ _growStrategy == b._growStrategy &&
+ _compactionStrategy == b._compactionStrategy &&
+ _predicateParams == b._predicateParams &&
+ (_basicType.type() != BasicType::Type::TENSOR ||
+ _tensorType == b._tensorType);
+}
+
}
diff --git a/searchcommon/src/vespa/searchcommon/attribute/config.h b/searchcommon/src/vespa/searchcommon/attribute/config.h
index 683b45b59e5..fe464736a6b 100644
--- a/searchcommon/src/vespa/searchcommon/attribute/config.h
+++ b/searchcommon/src/vespa/searchcommon/attribute/config.h
@@ -41,6 +41,7 @@ public:
bool getEnableOnlyBitVector() const { return _enableOnlyBitVector; }
bool getIsFilter() const { return _isFilter; }
+ bool isMutable() const { return _mutable; }
/**
* Check if this attribute should be fast accessible at all times.
@@ -50,19 +51,21 @@ public:
const GrowStrategy & getGrowStrategy() const { return _growStrategy; }
const CompactionStrategy &getCompactionStrategy() const { return _compactionStrategy; }
- void setHuge(bool v) { _huge = v; }
- void setFastSearch(bool v) { _fastSearch = v; }
- void setPredicateParams(const PredicateParams &v) { _predicateParams = v; }
- void setTensorType(const vespalib::eval::ValueType &tensorType_in) {
+ Config & setHuge(bool v) { _huge = v; return *this;}
+ Config & setFastSearch(bool v) { _fastSearch = v; return *this; }
+ Config & setPredicateParams(const PredicateParams &v) { _predicateParams = v; return *this; }
+ Config & setTensorType(const vespalib::eval::ValueType &tensorType_in) {
_tensorType = tensorType_in;
+ return *this;
}
/**
* Enable attribute posting list to consist of a bitvector in
* addition to (or instead of) a btree.
*/
- void setEnableBitVectors(bool enableBitVectors) {
+ Config & setEnableBitVectors(bool enableBitVectors) {
_enableBitVectors = enableBitVectors;
+ return *this;
}
/**
@@ -71,39 +74,22 @@ public:
* document frequency goes down, since recreated btree representation
* will then have lost weight information.
*/
- void setEnableOnlyBitVector(bool enableOnlyBitVector) {
+ Config & setEnableOnlyBitVector(bool enableOnlyBitVector) {
_enableOnlyBitVector = enableOnlyBitVector;
+ return *this;
}
/**
* Hide weight information when searching in attributes.
*/
- void setIsFilter(bool isFilter) {
- _isFilter = isFilter;
- }
+ Config & setIsFilter(bool isFilter) { _isFilter = isFilter; return *this; }
- void setFastAccess(bool v) { _fastAccess = v; }
+ Config & setMutable(bool isMutable) { _mutable = isMutable; return *this; }
+ Config & setFastAccess(bool v) { _fastAccess = v; return *this; }
Config & setGrowStrategy(const GrowStrategy &gs) { _growStrategy = gs; return *this; }
Config &setCompactionStrategy(const CompactionStrategy &compactionStrategy) { _compactionStrategy = compactionStrategy; return *this; }
bool operator!=(const Config &b) const { return !(operator==(b)); }
-
- bool
- operator==(const Config &b) const
- {
- return _basicType == b._basicType &&
- _type == b._type &&
- _huge == b._huge &&
- _fastSearch == b._fastSearch &&
- _enableBitVectors == b._enableBitVectors &&
- _enableOnlyBitVector == b._enableOnlyBitVector &&
- _isFilter == b._isFilter &&
- _fastAccess == b._fastAccess &&
- _growStrategy == b._growStrategy &&
- _compactionStrategy == b._compactionStrategy &&
- _predicateParams == b._predicateParams &&
- (_basicType.type() != BasicType::Type::TENSOR ||
- _tensorType == b._tensorType);
- }
+ bool operator==(const Config &b) const;
private:
BasicType _basicType;
@@ -114,6 +100,7 @@ private:
bool _enableOnlyBitVector;
bool _isFilter;
bool _fastAccess;
+ bool _mutable;
GrowStrategy _growStrategy;
CompactionStrategy _compactionStrategy;
PredicateParams _predicateParams;
diff --git a/searchlib/src/tests/attribute/attribute_operation/attribute_operation_test.cpp b/searchlib/src/tests/attribute/attribute_operation/attribute_operation_test.cpp
index 12bac6c6b20..bdd5682acb6 100644
--- a/searchlib/src/tests/attribute/attribute_operation/attribute_operation_test.cpp
+++ b/searchlib/src/tests/attribute/attribute_operation/attribute_operation_test.cpp
@@ -45,10 +45,11 @@ TEST("test illegal operations on float attribute") {
}
AttributeVector::SP
-createAttribute(BasicType basicType, const vespalib::string &fieldName, bool fastSearch = false)
+createAttribute(BasicType basicType, const vespalib::string &fieldName, bool fastSearch = false, bool immutable = false)
{
Config cfg(basicType, CollectionType::SINGLE);
- cfg.setFastSearch(fastSearch);
+ cfg.setMutable(!immutable)
+ .setFastSearch(fastSearch);
auto av = search::AttributeFactory::createAttribute(fieldName, cfg);
while (20 >= av->getNumDocs()) {
AttributeVector::DocId checkDocId(0u);
@@ -176,4 +177,11 @@ TEST("test that fastsearch attributes will fail to update") {
}
}
+TEST("test that immutable attributes will fail to update") {
+ auto attr = createAttribute(BasicType::INT64, "ai", true, false);
+ for (auto operation : {"++", "--", "+=7", "-=9", "*=3", "/=3", "%=3"}) {
+ TEST_DO(verify<int64_t>(BasicType::INT64, operation, *attr, 7, 7));
+ }
+}
+
TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_operation.cpp b/searchlib/src/vespa/searchlib/attribute/attribute_operation.cpp
index 5580fc25aef..0a81c5cb8b9 100644
--- a/searchlib/src/vespa/searchlib/attribute/attribute_operation.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/attribute_operation.cpp
@@ -94,7 +94,9 @@ struct UpdateFast {
op(operand)
{}
void operator()(uint32_t docid) { attr->set(docid, op(attr->getFast(docid))); }
- bool valid() const { return (attr != nullptr); }
+ bool valid() const {
+ return (attr != nullptr) &&
+ (dynamic_cast<const AttributeVector &>(*attr).getConfig().isMutable()); }
};
template <typename OP>