refactor(tvix): Use absl::btree_map for DerivationOutputs

This container implementation is much faster than std::map. We have
stuck to an ordered container because it's unclear whether the
accesses of this field (of which there are *many*) are actually
ordering dependent.

Also includes an Arbitrary implementation for absl::btree_map (for any
K, V that are also Arbitrary).

Change-Id: I04f58ca0ce32b9ae1759313b01508b0e44bae793
Reviewed-on: https://cl.tvl.fyi/c/depot/+/1683
Reviewed-by: glittershark <grfn@gws.fyi>
Tested-by: BuildkiteCI
This commit is contained in:
Vincent Ambo 2020-08-06 03:01:57 +01:00 committed by tazjin
parent a41c3dedb1
commit 91bd7ce73a
4 changed files with 22 additions and 7 deletions

View file

@ -40,8 +40,9 @@ BasicDerivation BasicDerivation::from_proto(
result.builder = proto_derivation->builder().path(); result.builder = proto_derivation->builder().path();
store.assertStorePath(result.builder); store.assertStorePath(result.builder);
result.outputs.insert(proto_derivation->outputs().begin(), for (auto [k, v] : proto_derivation->outputs()) {
proto_derivation->outputs().end()); result.outputs.emplace(k, v);
}
result.inputSrcs.insert(proto_derivation->input_sources().paths().begin(), result.inputSrcs.insert(proto_derivation->input_sources().paths().begin(),
proto_derivation->input_sources().paths().end()); proto_derivation->input_sources().paths().end());

View file

@ -2,6 +2,8 @@
#include <map> #include <map>
#include <absl/container/btree_map.h>
#include "libproto/worker.pb.h" #include "libproto/worker.pb.h"
#include "libstore/store-api.hh" #include "libstore/store-api.hh"
#include "libutil/hash.hh" #include "libutil/hash.hh"
@ -35,16 +37,16 @@ struct DerivationOutput {
void parseHashInfo(bool& recursive, Hash& hash) const; void parseHashInfo(bool& recursive, Hash& hash) const;
}; };
// TODO(grfn): change to absl::flat_hash_map // TODO(tazjin): Determine whether this actually needs to be ordered.
typedef std::map<std::string, DerivationOutput> DerivationOutputs; using DerivationOutputs = absl::btree_map<std::string, DerivationOutput>;
/* For inputs that are sub-derivations, we specify exactly which /* For inputs that are sub-derivations, we specify exactly which
output IDs we are interested in. */ output IDs we are interested in. */
// TODO(grfn): change to absl::flat_hash_map // TODO(grfn): change to absl::flat_hash_map
typedef std::map<Path, StringSet> DerivationInputs; using DerivationInputs = std::map<Path, StringSet>;
// TODO(grfn): change to absl::flat_hash_map // TODO(grfn): change to absl::flat_hash_map
typedef std::map<std::string, std::string> StringPairs; using StringPairs = std::map<std::string, std::string>;
struct BasicDerivation { struct BasicDerivation {
DerivationOutputs outputs; /* keyed on symbolic IDs */ DerivationOutputs outputs; /* keyed on symbolic IDs */
@ -54,7 +56,7 @@ struct BasicDerivation {
Strings args; Strings args;
StringPairs env; StringPairs env;
BasicDerivation(){}; BasicDerivation() = default;
// Convert the given proto derivation to a BasicDerivation in the given // Convert the given proto derivation to a BasicDerivation in the given
// nix::Store. // nix::Store.

View file

@ -5,6 +5,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <absl/container/btree_map.h>
#include <bits/stdint-intn.h> #include <bits/stdint-intn.h>
#include <gc/gc_cpp.h> #include <gc/gc_cpp.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>

View file

@ -22,6 +22,17 @@ namespace rc {
using nix::Derivation; using nix::Derivation;
using nix::DerivationOutput; using nix::DerivationOutput;
template <class K, class V>
struct Arbitrary<absl::btree_map<K, V>> {
static Gen<absl::btree_map<K, V>> arbitrary() {
return gen::map(gen::arbitrary<std::map<K, V>>(), [](std::map<K, V> map) {
absl::btree_map<K, V> out_map;
out_map.insert(map.begin(), map.end());
return out_map;
});
}
};
template <> template <>
struct Arbitrary<nix::Base> { struct Arbitrary<nix::Base> {
static Gen<nix::Base> arbitrary() { static Gen<nix::Base> arbitrary() {