aboutsummaryrefslogtreecommitdiffstats
path: root/document
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2020-08-14 18:48:09 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2020-08-14 18:48:09 +0000
commit729e8546d793a43ecfc94c11d5eed042d4dc74e1 (patch)
tree5923c808c8a83c8c617a949f98c30e5fce0c13cd /document
parentbbc768d6ef92f166717d65e67689f6aa15c98952 (diff)
Build the FieldSetRepo up front with all configured fieldsets to avoid building them for every get() call."
Diffstat (limited to 'document')
-rw-r--r--document/src/tests/fieldsettest.cpp17
-rw-r--r--document/src/vespa/document/datatype/documenttype.h7
-rw-r--r--document/src/vespa/document/fieldset/fieldsetrepo.cpp45
-rw-r--r--document/src/vespa/document/fieldset/fieldsetrepo.h10
4 files changed, 55 insertions, 24 deletions
diff --git a/document/src/tests/fieldsettest.cpp b/document/src/tests/fieldsettest.cpp
index 29581ff4549..af23e713735 100644
--- a/document/src/tests/fieldsettest.cpp
+++ b/document/src/tests/fieldsettest.cpp
@@ -31,7 +31,7 @@ TEST_F(FieldSetTest, testParsing)
(void) dynamic_cast<NoFields&>(*FieldSetRepo::parse(docRepo, NoFields::NAME));
(void) dynamic_cast<DocIdOnly&>(*FieldSetRepo::parse(docRepo, DocIdOnly::NAME));
- FieldSet::UP set = FieldSetRepo::parse(docRepo, "testdoctype1:headerval,content");
+ auto set = FieldSetRepo::parse(docRepo, "testdoctype1:headerval,content");
auto & coll = dynamic_cast<FieldCollection&>(*set);
std::ostringstream ost;
@@ -46,8 +46,8 @@ namespace {
bool checkContains(const DocumentTypeRepo& repo,
const std::string& str1, const std::string & str2) {
- FieldSet::UP set1 = FieldSetRepo::parse(repo, str1);
- FieldSet::UP set2 = FieldSetRepo::parse(repo, str2);
+ auto set1 = FieldSetRepo::parse(repo, str1);
+ auto set2 = FieldSetRepo::parse(repo, str2);
return set1->contains(*set2);
}
@@ -141,7 +141,7 @@ FieldSetTest::doCopyFields(const Document& src,
if (!dest) {
dest = &destDoc;
}
- FieldSet::UP fset = FieldSetRepo::parse(docRepo, fieldSetStr);
+ auto fset = FieldSetRepo::parse(docRepo, fieldSetStr);
FieldSet::copyFields(*dest, src, *fset);
return stringifyFields(*dest);
}
@@ -152,7 +152,7 @@ FieldSetTest::doStripFields(const Document& doc,
const std::string& fieldSetStr)
{
Document::UP copy(doc.clone());
- FieldSet::UP fset = FieldSetRepo::parse(docRepo, fieldSetStr);
+ auto fset = FieldSetRepo::parse(docRepo, fieldSetStr);
FieldSet::stripFields(*copy, *fset);
return stringifyFields(*copy);
}
@@ -198,7 +198,7 @@ FieldSetTest::doCopyDocument(const Document& src,
const DocumentTypeRepo& docRepo,
const std::string& fieldSetStr)
{
- FieldSet::UP fset = FieldSetRepo::parse(docRepo, fieldSetStr);
+ auto fset = FieldSetRepo::parse(docRepo, fieldSetStr);
Document::UP doc(FieldSet::createDocumentSubsetCopy(src, *fset));
return stringifyFields(*doc);
}
@@ -244,10 +244,9 @@ TEST_F(FieldSetTest, testSerialize)
"testdoctype1:content,hstringval"
};
- FieldSetRepo repo;
for (const char * fieldSet : fieldSets) {
- FieldSet::UP fs = FieldSetRepo::parse(docRepo, fieldSet);
- EXPECT_EQ(vespalib::string(fieldSet), repo.serialize(*fs));
+ auto fs = FieldSetRepo::parse(docRepo, fieldSet);
+ EXPECT_EQ(vespalib::string(fieldSet), FieldSetRepo::serialize(*fs));
}
}
diff --git a/document/src/vespa/document/datatype/documenttype.h b/document/src/vespa/document/datatype/documenttype.h
index ed6e9e66ab5..fae65addb48 100644
--- a/document/src/vespa/document/datatype/documenttype.h
+++ b/document/src/vespa/document/datatype/documenttype.h
@@ -61,12 +61,10 @@ public:
DocumentType();
DocumentType(vespalib::stringref name, int32_t id);
- DocumentType(vespalib::stringref name, int32_t id,
- const StructDataType& fields);
+ DocumentType(vespalib::stringref name, int32_t id, const StructDataType& fields);
explicit DocumentType(vespalib::stringref name);
- DocumentType(vespalib::stringref name,
- const StructDataType& fields);
+ DocumentType(vespalib::stringref name, const StructDataType& fields);
~DocumentType() override;
@@ -101,6 +99,7 @@ public:
DocumentType & addFieldSet(const vespalib::string & name, FieldSet::Fields fields);
const FieldSet * getFieldSet(const vespalib::string & name) const;
+ const FieldSetMap & getFieldSets() const { return _fieldSets; }
const ImportedFieldNames& imported_field_names() const noexcept {
return _imported_field_names;
diff --git a/document/src/vespa/document/fieldset/fieldsetrepo.cpp b/document/src/vespa/document/fieldset/fieldsetrepo.cpp
index 33cbf6185c4..5bde291c8dd 100644
--- a/document/src/vespa/document/fieldset/fieldsetrepo.cpp
+++ b/document/src/vespa/document/fieldset/fieldsetrepo.cpp
@@ -5,6 +5,7 @@
#include <vespa/vespalib/util/exceptions.h>
#include <vespa/vespalib/stllike/asciistream.h>
#include <vespa/document/repo/documenttyperepo.h>
+#include <vespa/vespalib/stllike/hash_map.hpp>
using vespalib::StringTokenizer;
@@ -12,27 +13,25 @@ namespace document {
namespace {
-FieldSet::UP
+FieldSet::SP
parseSpecialValues(vespalib::stringref name)
{
- FieldSet::UP fs;
if ((name.size() == 4) && (name[1] == 'i') && (name[2] == 'd') && (name[3] == ']')) {
- fs = std::make_unique<DocIdOnly>();
+ return std::make_shared<DocIdOnly>();
} else if ((name.size() == 5) && (name[1] == 'a') && (name[2] == 'l') && (name[3] == 'l') && (name[4] == ']')) {
- fs = std::make_unique<AllFields>();
+ return std::make_shared<AllFields>();
} else if ((name.size() == 6) && (name[1] == 'n') && (name[2] == 'o') && (name[3] == 'n') && (name[4] == 'e') && (name[5] == ']')) {
- fs = std::make_unique<NoFields>();
+ return std::make_shared<NoFields>();
} else if ((name.size() == 7) && (name[1] == 'd') && (name[2] == 'o') && (name[3] == 'c') && (name[4] == 'i') && (name[5] == 'd') && (name[6] == ']')) {
- fs = std::make_unique<DocIdOnly>();
+ return std::make_shared<DocIdOnly>();
} else {
throw vespalib::IllegalArgumentException(
"The only special names (enclosed in '[]') allowed are "
"id, all, none, not '" + name + "'.");
}
- return fs;
}
-FieldSet::UP
+FieldSet::SP
parseFieldCollection(const DocumentTypeRepo& repo,
vespalib::stringref docType,
vespalib::stringref fieldNames)
@@ -55,12 +54,12 @@ parseFieldCollection(const DocumentTypeRepo& repo,
builder.add(&type.getField(token));
}
}
- return std::make_unique<FieldCollection>(type, builder.build());
+ return std::make_shared<FieldCollection>(type, builder.build());
}
}
-FieldSet::UP
+FieldSet::SP
FieldSetRepo::parse(const DocumentTypeRepo& repo, vespalib::stringref str)
{
if (str[0] == '[') {
@@ -111,5 +110,31 @@ FieldSetRepo::serialize(const FieldSet& fieldSet)
}
}
+
+FieldSetRepo::FieldSetRepo(const DocumentTypeRepo& repo)
+ : _doumentTyperepo(repo),
+ _configuredFieldSets()
+{
+ repo.forEachDocumentType(*vespalib::makeClosure(this, &FieldSetRepo::configureDocumentType));
+}
+FieldSetRepo::~FieldSetRepo() = default;
+
+void
+FieldSetRepo::configureDocumentType(const DocumentType & documentType) {
+ for (const auto & entry : documentType.getFieldSets()) {
+ vespalib::string fieldSetName(documentType.getName());
+ fieldSetName.append(':').append(entry.first);
+ _configuredFieldSets[fieldSetName] = parse(_doumentTyperepo, fieldSetName);
+ }
+}
+FieldSet::SP
+FieldSetRepo::getFieldSet(vespalib::stringref fieldSetString) const {
+ auto found = _configuredFieldSets.find(fieldSetString);
+ if (found != _configuredFieldSets.end()) {
+ return found->second;
+ }
+ return parse(_doumentTyperepo, fieldSetString);
+}
+
}
diff --git a/document/src/vespa/document/fieldset/fieldsetrepo.h b/document/src/vespa/document/fieldset/fieldsetrepo.h
index bfe9c05d1ca..d213230848a 100644
--- a/document/src/vespa/document/fieldset/fieldsetrepo.h
+++ b/document/src/vespa/document/fieldset/fieldsetrepo.h
@@ -16,9 +16,17 @@ class DocumentTypeRepo;
class FieldSetRepo
{
public:
- static FieldSet::UP parse(const DocumentTypeRepo& repo, vespalib::stringref fieldSetString);
+ FieldSetRepo(const DocumentTypeRepo& repo);
+ ~FieldSetRepo();
+ FieldSet::SP getFieldSet(vespalib::stringref fieldSetString) const;
+
+ static FieldSet::SP parse(const DocumentTypeRepo& repo, vespalib::stringref fieldSetString);
static vespalib::string serialize(const FieldSet& fs);
+private:
+ void configureDocumentType(const DocumentType & documentType);
+ const DocumentTypeRepo & _doumentTyperepo;
+ vespalib::hash_map<vespalib::string, FieldSet::SP> _configuredFieldSets;
};
}