-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FDB-303 added decoupling between Key and fully typed 'CanonicalKey' #26
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #26 +/- ##
===========================================
+ Coverage 63.84% 64.12% +0.27%
===========================================
Files 237 238 +1
Lines 13583 13610 +27
Branches 1325 1313 -12
===========================================
+ Hits 8672 8727 +55
+ Misses 4911 4883 -28 ☔ View full report in Codecov by Sentry. |
src/fdb5/rules/Schema.cc
Outdated
void Schema::expand(const Key &field, WriteVisitor &visitor) const { | ||
Key full(registry()); | ||
std::vector<Key> keys(3); | ||
void Schema::expand(const CanonicalKey& field, WriteVisitor &visitor) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels the wrong way around - we are expanding a canonicalised key, and producing a non-canonicalised key?
src/fdb5/api/FDB.h
Outdated
@@ -75,7 +75,7 @@ class FDB { | |||
// warning: not high-perf API - makes sure that all the requested fields are archived and there are no data exceeding the request | |||
void archive(const metkit::mars::MarsRequest& request, eckit::DataHandle& handle); | |||
// disclaimer: this is a low-level API. The provided key and the corresponding data are not checked for consistency | |||
void archive(const Key& key, const void* data, size_t length); | |||
void archive(const CanonicalKey& key, const void* data, size_t length); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was expecting the interface to use ApiKey?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Or just "Key" to make it nice and clean)
src/fdb5/database/Key.h
Outdated
public: // methods | ||
|
||
explicit CanonicalKey(const std::shared_ptr<TypesRegistry> reg = nullptr); | ||
explicit CanonicalKey(eckit::Stream &, const std::shared_ptr<TypesRegistry> reg = nullptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand (a) why CanonicalKey and ApiKey have the same constructors, (b) why they both accept knowledge of the TypesRegistry.
Ideally neither of them will have the TypesRegistry. We should have an uncanonicalised key, then a component (the schema?) which has the TypesRegistry and produces a canonicalised key.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some minor comment, mostly things of which I'm sure I'm just lacking information, as well as some commented code which is probably not necessary anymore.
src/fdb5/api/FDB.cc
Outdated
@@ -112,7 +112,7 @@ void FDB::archive(const Key& key, const void* data, size_t length) { | |||
if (stepunit->second.size()>0 && static_cast<char>(tolower(stepunit->second[0])) != 'h') { | |||
auto step = keyInternal.find("step"); | |||
if (step != keyInternal.end()) { | |||
std::string canonicalStep = config().schema().registry()->lookupType("step").toKey("step", step->second + static_cast<char>(tolower(stepunit->second[0]))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the toKey
method now is the same as the tidy
method. We should get rid of one
@@ -35,13 +35,11 @@ const std::string &Type::type() const { | |||
return type_; | |||
} | |||
|
|||
std::string Type::tidy(const std::string&, | |||
const std::string &value) const { | |||
std::string Type::tidy(const std::string &value) const { | |||
return value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above
src/fdb5/database/Key.cc
Outdated
@@ -380,27 +380,15 @@ Key::Key() : | |||
// } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are quite a lot of comments in the class. Is the code still needed? If not, remove it.
src/fdb5/toc/TocCatalogueWriter.cc
Outdated
@@ -62,7 +62,7 @@ bool TocCatalogueWriter::selectIndex(const Key& idxKey) { | |||
fdb5LustreapiFileCreate(indexPath.localPath(), stripeIndexLustreSettings()); | |||
} | |||
|
|||
indexes_[idxKey] = Index(new TocIndex(idxKey, indexPath, 0, TocIndex::WRITE)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The whole Catalouge is inserted here although only the schema (and maybe the key functionality/ dbKey) is needed. Is there any reason to insert the whole thing?
How are we treating raw pointer? Is this, per convention, interpreted as a transferred ownership? If so, we need a shared_pointer or whatever the convention is here.
@@ -1035,7 +1035,7 @@ std::vector<Index> TocHandler::loadIndexes(bool sorted, | |||
s >> offset; | |||
s >> type; | |||
LOG_DEBUG(debug, LibFdb5) << "TocRecord TOC_INDEX " << path << " - " << offset << std::endl; | |||
indexes.push_back( new TocIndex(s, r->header_.serialisationVersion_, currentDirectory(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The remark above would probably get rid of this dynamic_cast, as well? Not entirely sure, whether this can be done like suggested.
@@ -34,7 +34,11 @@ TypeClimateMonthly::~TypeClimateMonthly() { | |||
|
|||
static int month(const std::string &value) { | |||
if (isdigit(value[0])) { | |||
eckit::Date date(value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is this coming from? Could you add a comment highlighting why this differentiation is necessary?
@@ -19,6 +19,7 @@ if (HAVE_FDB_BUILD_TOOLS) # test scripts use the fdb tools | |||
add_subdirectory(FDB-282) | |||
add_subdirectory(FDB-291) | |||
add_subdirectory(FDB-292) | |||
add_subdirectory(FDB-303) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's no FDB-303 directory, forgot to commit ?
@@ -48,8 +52,7 @@ static int month(const std::string &value) { | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation is weird here (predates this PR)
src/fdb5/database/Key.cc
Outdated
|
||
return ret; | ||
} | ||
BaseKey::~BaseKey() {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prefer = default;
src/fdb5/database/Key.cc
Outdated
for (eckit::StringDict::const_iterator i = keys_.begin(); i != keys_.end(); ++i) { | ||
s << i->first << (registry ? canonicalise(i->first, i->second) : i->second); | ||
s << i->first << canonicalise(i->first, i->second); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
readable ?
for (const auto& [keyword, value] : keys_) { s << keyword << canonicalise(keyword, value); }
std::vector<std::string>::const_iterator k = p.begin(); | ||
std::vector<std::string>::const_iterator kend = p.end(); | ||
for (; k != kend; ++k) { | ||
for (const auto& k : request.params()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
naming; k => keyword
src/fdb5/database/Key.cc
Outdated
bool found=false; | ||
auto values = request.values(k); | ||
std::string can = canonicalise(k, j->second); | ||
for (auto it = values.begin(); !found && it != values.end(); it++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cbegin()
would be better
it++
intentional ?
src/fdb5/database/Key.cc
Outdated
//---------------------------------------------------------------------------------------------------------------------- | ||
|
||
Key::Key() : | ||
BaseKey() {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
redundant BaseKey()
init
src/fdb5/database/Key.cc
Outdated
BaseKey(keys) {} | ||
|
||
Key::Key(eckit::Stream& s) : | ||
BaseKey() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
redundant BaseKey()
init
src/fdb5/database/RetrieveVisitor.h
Outdated
@@ -42,11 +42,11 @@ class RetrieveVisitor : public ReadVisitor { | |||
|
|||
// From Visitor | |||
|
|||
virtual bool selectDatabase(const Key &key, const Key &full) override; | |||
virtual bool selectDatabase(const Key& dbKey, const TypedKey& fullComputedKey) override; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can remove virtual
, also below
src/fdb5/database/Store.h
Outdated
@@ -36,7 +36,7 @@ class Store { | |||
virtual ~Store() {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prefer = default;
src/fdb5/database/Store.h
Outdated
@@ -36,7 +36,7 @@ class Store { | |||
virtual ~Store() {} | |||
|
|||
virtual eckit::DataHandle* retrieve(Field& field) const = 0; | |||
virtual std::unique_ptr<FieldLocation> archive(const Key &key, const void *data, eckit::Length length) = 0; | |||
virtual std::unique_ptr<FieldLocation> archive(const Key& idxKey, const void *data, eckit::Length length) = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing include memory
src/fdb5/message/MessageArchiver.cc
Outdated
@@ -85,7 +85,7 @@ static std::vector<metkit::mars::MarsRequest> make_filter_requests(const std::st | |||
|
|||
if(str.empty()) return std::vector<metkit::mars::MarsRequest>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could be return {};
@@ -85,7 +85,7 @@ static std::vector<metkit::mars::MarsRequest> make_filter_requests(const std::st | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can move make_filter_requests
to anonym namespace and remove static
src/fdb5/rules/Predicate.h
Outdated
@@ -26,6 +26,7 @@ namespace metkit { class MarsRequest; } | |||
|
|||
namespace fdb5 { | |||
|
|||
class Key; | |||
class Key; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be TypedKey
|
||
if ((*cur)->match(k)) | ||
expand(request, next, depth, keys, full, visitor); | ||
if ((*cur)->match(k.canonical())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
attention, do we need k.canonical here, since visitor::values are canonical ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume that match() takes an argument of type BaseKey. We should either:
i. Call canonical() inside the match() function, or
ii. Be incrementally canonicalising such that we don't fully canonicalise k (with lots of work and allocations) for each iteration of the for loop.
src/fdb5/daos/DaosIndex.cc
Outdated
@@ -34,8 +34,8 @@ namespace fdb5 { | |||
|
|||
//---------------------------------------------------------------------------------------------------------------------- | |||
|
|||
DaosIndex::DaosIndex(const Key& key, const fdb5::DaosName& name) : | |||
IndexBase(key, "daosKeyValue"), | |||
DaosIndex::DaosIndex(const Key& key, const Catalogue* catalogue, const fdb5::DaosName& name) : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the policy on handling raw pointers? Is this owner ship transferal? Would a shared pointer be ok, otherwise?
src/fdb5/daos/DaosIndex.h
Outdated
@@ -27,9 +27,9 @@ class DaosIndex : public IndexBase { | |||
public: // methods | |||
|
|||
/// @note: creates a new index in DAOS, in the container pointed to by 'name' | |||
DaosIndex(const Key& key, const fdb5::DaosName& name); | |||
DaosIndex(const Key& key, const Catalogue* catalogue, const fdb5::DaosName& name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See raw pointer comment above.
src/fdb5/database/Index.h
Outdated
@@ -121,6 +123,9 @@ class IndexBase : public eckit::Counted { | |||
|
|||
Indexer indexer_; | |||
|
|||
const Catalogue* catalogue_; | |||
mutable std::shared_ptr<TypesRegistry> registry_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also consistency between the raw pointer and shared pointer concept.
src/fdb5/database/Key.cc
Outdated
Key::Key(const std::shared_ptr<TypesRegistry> reg, bool canonical) : | ||
keys_(), | ||
registry_(reg), canonical_(canonical) {} | ||
// BaseKey::BaseKey(const std::shared_ptr<TypesRegistry> reg) : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comments can be deleted.
src/fdb5/database/Key.cc
Outdated
void Key::encode(eckit::Stream& s) const { | ||
const TypesRegistry* registry = canonical_ ? nullptr : &this->registry(); | ||
void BaseKey::encode(eckit::Stream& s) const { | ||
// const TypesRegistry* registry = (registry_ ? registry_.get() : nullptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment.
src/fdb5/rules/Schema.cc
Outdated
|
||
for (std::vector<Rule *>::const_iterator i = rules_.begin(); i != rules_.end(); ++i ) { | ||
for (Rule* r : rules_) { | ||
// eckit::Log::info() << "Rule " << **i << std::endl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment.
src/fdb5/toc/RootManager.cc
Outdated
std::vector<PathName> RootManager::allRoots(const Key& key) | ||
{ | ||
eckit::StringSet roots; | ||
// std::vector<PathName> RootManager::allRoots(const Key& key) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment.
|
||
/// Lists the roots that can be visited given a DB key | ||
std::vector<eckit::PathName> allRoots(const Key& key); | ||
// std::vector<eckit::PathName> allRoots(const Key& key); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implementation has been removed. So remove this.
@@ -74,20 +74,20 @@ bool TocCatalogueWriter::selectIndex(const Key& key) { | |||
|
|||
if (useSubToc()) { | |||
|
|||
if (fullIndexes_.find(key) == fullIndexes_.end()) { | |||
if (fullIndexes_.find(idxKey) == fullIndexes_.end()) { | |||
|
|||
// TODO TODO TODO .master.index |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to be rather important, if it is stated thrice. Or simply delete it.
@@ -151,11 +151,11 @@ void TocCatalogueWriter::reconsolidateIndexesAndTocs() { | |||
writer_(writer) {} | |||
~ConsolidateIndexVisitor() override {} | |||
private: | |||
void visitDatum(const Field& field, const Key& key) override { | |||
void visitDatum(const Field& field, const TypedKey& datumKey) override { | |||
// TODO: Do a sneaky schema.expand() here, prepopulated with the current DB/index/Rule, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this todo still valid?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. Remove it.
@@ -129,7 +129,7 @@ void MultiRetrieveVisitor::values(const metkit::mars::MarsRequest &request, | |||
} | |||
|
|||
for(auto l: list) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
avoid copy; for (const auto& l : list) {
naming; l -> value
@@ -21,6 +21,7 @@ | |||
|
|||
#include "fdb5/database/DB.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unused include
(in general, the DB-Catalogue-Store
trio has include issues among each other)
auto step = keyInternal.find("step"); | ||
if (step != keyInternal.end()) { | ||
std::string canonicalStep = keyInternal.registry().lookupType("step").toKey("step", step->second+stepunit->second); | ||
std::string canonicalStep = config().schema().registry()->lookupType("step").toKey(step->second + static_cast<char>(tolower(stepunit->second[0]))); | ||
keyInternal.set("step", canonicalStep); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
elegant to move registry out of the key
can we pin the registry
above and reuse it in the loop, such as;
Key keyInternal(key);
const auto registry = config().schema().registry();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which loop are you referring to here? I don't see a loop.
src/fdb5/api/FDB.cc
Outdated
#include "eckit/utils/StringTools.h" | ||
|
||
#include "eckit/system/Plugin.h" | ||
#include "eckit/system/LibraryManager.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unused includes
@@ -26,7 +26,6 @@ class Catalogue; | |||
class Store; | |||
class FDBToolRequest; | |||
class Index; | |||
class Key; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TypedKey
?
src/fdb5/database/Index.cc
Outdated
@@ -125,28 +128,38 @@ void IndexBase::encodeLegacy(eckit::Stream& s, const int version) const { | |||
s << type_; | |||
} | |||
|
|||
void IndexBase::put(const Key &key, const Field &field) { | |||
void IndexBase::put(const Key& key, const Field &field) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe align both refs to left for consistency
src/fdb5/toc/AdoptVisitor.h
Outdated
@@ -33,14 +33,14 @@ class AdoptVisitor : public BaseArchiveVisitor { | |||
public: // methods | |||
|
|||
AdoptVisitor(Archiver &owner, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
align all
refs to left ?
src/fdb5/toc/AdoptVisitor.h
Outdated
|
||
virtual bool selectDatum(const Key &key, const Key &full) override; | ||
virtual bool selectDatum(const TypedKey& datumKey, const TypedKey& fullComputedKey) override; | ||
|
||
virtual void print( std::ostream &out ) const override; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing (forward) decl -> TypedKey
redundant virtual
s
src/fdb5/toc/AdoptVisitor.cc
Outdated
@@ -20,23 +20,23 @@ namespace fdb5 { | |||
|
|||
//---------------------------------------------------------------------------------------------------------------------- | |||
|
|||
AdoptVisitor::AdoptVisitor(Archiver &owner, const Key &field, const PathName &path, Offset offset, Length length) : | |||
BaseArchiveVisitor(owner, field), | |||
AdoptVisitor::AdoptVisitor(Archiver &owner, const Key& initialFieldKey, const PathName &path, Offset offset, Length length) : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good practice -> add const
to offset and length
@@ -173,7 +173,7 @@ void DB::reconsolidate() { | |||
cat->reconsolidate(); | |||
} | |||
|
|||
void DB::index(const Key &key, const eckit::PathName &path, eckit::Offset offset, eckit::Length length) { | |||
void DB::index(const Key& key, const eckit::PathName &path, eckit::Offset offset, eckit::Length length) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good practice -> const
offset and length
for (const auto& m : matching_) { | ||
const Index& idx(m->first); | ||
Key remapKey = m->second; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
safer:
for (const auto* match : matching_) {
*if (!match) { continue; }*
const auto& [idx, remapKey] = *match;
better, matching_
-> replace with std::forward_list<const pair<>&> or use std::vector<std::reference_wrapper<>>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
attention, matching_
contains ptr (not ref); guard as in my comment above or ASSERT()
@@ -151,11 +151,11 @@ void TocCatalogueWriter::reconsolidateIndexesAndTocs() { | |||
writer_(writer) {} | |||
~ConsolidateIndexVisitor() override {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
off topic:
redundant dtor, avoid it! no use, on top it disables move semantics (if any) on inheritance
@@ -52,7 +51,7 @@ class EntryVisitor : public eckit::NonCopyable { | |||
|
|||
private: // methods | |||
|
|||
virtual void visitDatum(const Field& field, const Key& key) = 0; | |||
virtual void visitDatum(const Field& field, const TypedKey& datumKey) = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
critical decision to choose TypeKey
here..
if all visitDatum implementations need Key
(hence each calls canocinal), then leave it as Key
and let parent do it ..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, using TypedKey is correct.
This defers the decision on whether we need to do canonicalisation (which is expensive) to the class which does the using.
src/fdb5/toc/TocCatalogueWriter.h
Outdated
virtual bool selectIndex(const Key& idxKey) override; | ||
virtual void deselectIndex() override; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
chance to remove virtual
src/fdb5/database/Index.h
Outdated
@@ -53,8 +53,8 @@ class IndexBase : public eckit::Counted { | |||
|
|||
public: // methods | |||
|
|||
IndexBase(const Key& key, const std::string& type); | |||
IndexBase(eckit::Stream& s, const int version); | |||
IndexBase(const Key& key, const std::string& type, const Catalogue* catalogue); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not this PR but mismatched ordering
@@ -161,7 +161,7 @@ class TocStatsReportVisitor : public virtual StatsReportVisitor { | |||
|
|||
bool visitDatabase(const Catalogue& catalogue, const Store& store) override; | |||
void visitDatum(const Field& field, const std::string& keyFingerprint) override; | |||
void visitDatum(const Field& field, const Key& key) override { NOTIMP; } | |||
void visitDatum(const Field& field, const TypedKey& datumKey) override { NOTIMP; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
attention #26 (comment)
@@ -128,7 +128,7 @@ std::unique_ptr<FieldLocation> TocStore::archive(const Key &key, const void *dat | |||
|
|||
ASSERT(len == length); | |||
|
|||
return std::unique_ptr<TocFieldLocation>(new TocFieldLocation(dataPath, position, length, Key(nullptr, true))); | |||
return std::unique_ptr<TocFieldLocation>(new TocFieldLocation(dataPath, position, length, Key())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
while at it, fix -> std::make_unique(dataPath, position, length, Key())
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can do. It doesn't really matter (the only case where std::make_unique makes a difference is if you have a constructor to an object which owns multiple dynamically allocated objects, where the constructor of one of those objects throws after the other has been constructed, and you want to ensure there is no memory leak.
src/fdb5/tools/fdb-hide.cc
Outdated
ASSERT(schema.expandFirstLevel(dbrequest.request(), dbkey)); | ||
|
||
std::unique_ptr<Catalogue> db = CatalogueFactory::instance().build(dbkey, conf, true); | ||
std::unique_ptr<Catalogue> db = CatalogueFactory::instance().build(dbkey.canonical(), conf, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
db and dbWrited (below) could share a const auto dbCanonicalKey = dbkey.canonical();
@@ -65,16 +65,16 @@ void FdbRoot::execute(const eckit::option::CmdArgs& args) { | |||
|
|||
Config conf = config(args); | |||
const Schema& schema = conf.schema(); | |||
Key result; | |||
TypedKey result{conf.schema().registry()}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dbReader and dbWriter (below) could share a const auto key = result.canonical();
for (BaseKey::const_iterator j = other.begin(); j != other.end(); ++j) { | ||
const std::string& keyword = (*j).first; | ||
BaseKey::const_iterator k = find(keyword); | ||
if (k == keys_.end()) { | ||
missing.insert(keyword); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice catch!
auto
?
keys_.end() -> end()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
small thing but keys_.end()
-> end()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very well done. There's opportunity to fix some non-pr code quality issues. Couple of things need attention, but there's a major issue of segfault, which's why I cannot approve it. Please see the attention/critical
comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's an object slicing, pls see my comment above.
protected: // members | ||
|
||
const Key& field_; | ||
const Key& initialFieldKey() { return initialFieldKey_; } | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing const
-> const Key& initialFieldKey() const { return initialFieldKey_; }
for (BaseKey::const_iterator j = other.begin(); j != other.end(); ++j) { | ||
const std::string& keyword = (*j).first; | ||
BaseKey::const_iterator k = find(keyword); | ||
if (k == keys_.end()) { | ||
missing.insert(keyword); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
small thing but keys_.end()
-> end()
src/fdb5/database/FieldLocation.cc
Outdated
const std::string& keyStr = uri.query("remapKey"); | ||
if (!keyStr.empty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
simply const std::string
, no ref
src/fdb5/database/Key.cc
Outdated
BaseKey(key), registry_(reg) {} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
attention, object slicing will cause issues later
we can reduce contention as registry_(std::move(req))
src/fdb5/database/Key.cc
Outdated
BaseKey(key), registry_(reg) {} | ||
|
||
TypedKey::TypedKey(std::shared_ptr<const TypesRegistry> reg) : | ||
BaseKey({}), registry_(reg) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can remove BaseKey({})
since we have default ctor
we can reduce contention as registry_(std::move(req))
virtual void getValues(const metkit::mars::MarsRequest &request, | ||
const std::string &keyword, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could remove virtual
|
||
virtual std::string toKey(const std::string& keyword, | ||
const std::string& value) const override; | ||
std::string toKey(const std::string& value) const override; | ||
|
||
virtual void getValues(const metkit::mars::MarsRequest &request, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could remove virtual
@@ -28,7 +28,7 @@ class TypeParam : public Type { | |||
|
|||
TypeParam(const std::string &name, const std::string &type); | |||
|
|||
virtual ~TypeParam() override; | |||
~TypeParam() override; | |||
|
|||
virtual void getValues(const metkit::mars::MarsRequest &request, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
more virtual
@@ -28,22 +28,21 @@ class TypeStep : public Type { | |||
|
|||
TypeStep(const std::string &name, const std::string &type); | |||
|
|||
virtual ~TypeStep() override; | |||
~TypeStep() override; | |||
|
|||
virtual void getValues(const metkit::mars::MarsRequest &request, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can remove virtual
for (const auto& m : matching_) { | ||
const Index& idx(m->first); | ||
Key remapKey = m->second; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
attention, matching_
contains ptr (not ref); guard as in my comment above or ASSERT()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please look in Schema.h/cc at the ownership of the TypesRegistry. It is currently a shared_ptr - this was because the types registry could be accessed by the Key object, and we could not guarantee that the lifetime of Key objects was less than the lifetime of the schema, as they were returned by the API.
I believe that now all items returned over the API are 'clean' in this regard, and do not require extension of the life of the TypesRegistry - so this should be able to belong to the Schema (and be accessed by reference from elsewhere). If we can fix this, it is a strong indication that we have removed a code smell.
Overall I am really happy with this PR. Once the comments have been addressed, I'm happy for Emanuele to merge without further review from me.
|
||
//TODO add unit test for each type | ||
std::string canonicalise(const std::string& keyword, const std::string& value) const; | ||
virtual std::string canonicalise(const std::string& keyword, const std::string& value) const = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do canonicalise() and type() belong to the base class - surely these are functions that can only be called on one of the derived classes?
|
||
private: // members | ||
|
||
std::string canonicalise(const std::string& keyword, const std::string& value) const override; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a comment to effect that this method is used in the comparison function when passed a BaseKey (otherwise it is odd that this method exists)
private: // members | ||
|
||
std::string canonicalise(const std::string& keyword, const std::string& value) const override; | ||
std::string type(const std::string& keyword) const override; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function should never be called on Key (only ever on TypedKey). Please remove it from here and from the base class.
auto step = keyInternal.find("step"); | ||
if (step != keyInternal.end()) { | ||
std::string canonicalStep = keyInternal.registry().lookupType("step").toKey("step", step->second+stepunit->second); | ||
std::string canonicalStep = config().schema().registry()->lookupType("step").toKey(step->second + static_cast<char>(tolower(stepunit->second[0]))); | ||
keyInternal.set("step", canonicalStep); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which loop are you referring to here? I don't see a loop.
@@ -52,7 +51,7 @@ class EntryVisitor : public eckit::NonCopyable { | |||
|
|||
private: // methods | |||
|
|||
virtual void visitDatum(const Field& field, const Key& key) = 0; | |||
virtual void visitDatum(const Field& field, const TypedKey& datumKey) = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, using TypedKey is correct.
This defers the decision on whether we need to do canonicalisation (which is expensive) to the class which does the using.
@@ -151,11 +151,11 @@ void TocCatalogueWriter::reconsolidateIndexesAndTocs() { | |||
writer_(writer) {} | |||
~ConsolidateIndexVisitor() override {} | |||
private: | |||
void visitDatum(const Field& field, const Key& key) override { | |||
void visitDatum(const Field& field, const TypedKey& datumKey) override { | |||
// TODO: Do a sneaky schema.expand() here, prepopulated with the current DB/index/Rule, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. Remove it.
src/fdb5/toc/TocHandler.cc
Outdated
@@ -1035,7 +1035,7 @@ std::vector<Index> TocHandler::loadIndexes(bool sorted, | |||
s >> offset; | |||
s >> type; | |||
LOG_DEBUG(debug, LibFdb5) << "TocRecord TOC_INDEX " << path << " - " << offset << std::endl; | |||
indexes.push_back( new TocIndex(s, r->header_.serialisationVersion_, currentDirectory(), | |||
indexes.push_back( new TocIndex(s, *(dynamic_cast<const TocCatalogue*>(this)), r->header_.serialisationVersion_, currentDirectory(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like this at all.
The purpose of dynamic_cast is that it uses RTTI to check that the cast is valid - and returns null if not. Here we are assuming that the return value is non-null without checking - either negating the point (which is that it should be used where we cannot assume this), or creating a possible segfault location.
One alternative would be to use dynamic_cast<const TocCatalogue&> which would throw an exception in the case that this was wrong.
Another would be to use a static_cast. Or (at the top of the function) we could ASSERT that the dynamic cast is non-null, and then use the returned value elsewhere in the function.
But this is telling us that something is not right with the type hierarchy. Either this function ought to move to TocCatalogue, or it ought to accept an argument of type "const Catalogue&". Probably the latter.
This code is smelly.
@@ -128,7 +128,7 @@ std::unique_ptr<FieldLocation> TocStore::archive(const Key &key, const void *dat | |||
|
|||
ASSERT(len == length); | |||
|
|||
return std::unique_ptr<TocFieldLocation>(new TocFieldLocation(dataPath, position, length, Key(nullptr, true))); | |||
return std::unique_ptr<TocFieldLocation>(new TocFieldLocation(dataPath, position, length, Key())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can do. It doesn't really matter (the only case where std::make_unique makes a difference is if you have a constructor to an object which owns multiple dynamically allocated objects, where the constructor of one of those objects throws after the other has been constructed, and you want to ensure there is no memory leak.
@@ -34,7 +34,11 @@ TypeClimateMonthly::~TypeClimateMonthly() { | |||
|
|||
static int month(const std::string &value) { | |||
if (isdigit(value[0])) { | |||
eckit::Date date(value); | |||
int n = stoi(value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we check that the string length <= 2 here. Otherwise we will be doing a lot of extra string work in most cases.
set +e | ||
grep "Invalid expver value xxxx" out.1 # should fail | ||
set -e | ||
! grep "Invalid expver value xxxx" out.1 # should fail |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice trick. I didn't know this one.
No description provided.