zeek/src/script_opt/CPP/Tracker.h
Vern Paxson 134f8f2ef5 script optimization fixes:
new initialization model for standalone C++ scripts
 type coercion fix
 ZAM fix for compiling using C++ optimizer
 disambiguate empty constructors
2022-11-20 12:16:25 -08:00

83 lines
2.7 KiB
C++

// See the file "COPYING" in the main distribution directory for copyright.
// C++ compiler helper class that tracks distinct instances of a given key,
// where the key can have any IntrusivePtr type. The properties of a
// tracker are that it (1) supports a notion that two technically distinct
// keys in fact reflect the same underlying object, (2) provides an
// instance of such keys to consistently serve as their "representative", and
// (3) provides names (suitable for use as C++ variables) for representative
// keys.
//
// Notions of "same" are taken from hash values ala those provided by
// ProfileFunc.
#pragma once
#include "zeek/script_opt/CPP/InitsInfo.h"
namespace zeek::detail
{
// T is a type that has an IntrusivePtr instantiation.
template <class T> class CPPTracker
{
public:
// The base name is used to construct key names. "single_global",
// if true, specifies that the names should be constructed as
// indexes into a single global, rather than as distinct globals.
CPPTracker(const char* _base_name, bool _single_global)
: base_name(_base_name), single_global(_single_global)
{
}
// True if the given key has already been entered.
bool HasKey(const T* key) const { return map.count(key) > 0; }
bool HasKey(IntrusivePtr<T> key) const { return HasKey(key.get()); }
// Only adds the key if it's not already present.
void AddKey(IntrusivePtr<T> key, p_hash_type h);
void AddInitInfo(const T* rep, std::shared_ptr<CPP_InitInfo> gi) { gi_s[rep] = std::move(gi); }
// Returns the (C++ variable) name associated with the given key.
std::string KeyName(const T* key);
std::string KeyName(IntrusivePtr<T> key) { return KeyName(key.get()); }
// Returns all of the distinct keys entered into the tracker.
// A key is "distinct" if it's a representative.
const std::vector<IntrusivePtr<T>>& DistinctKeys() const { return keys; }
// For a given key, get its representative.
const T* GetRep(const T* key)
{
ASSERT(HasKey(key));
return reps[map[key]];
}
const T* GetRep(IntrusivePtr<T> key) { return GetRep(key.get()); }
private:
// Maps keys to internal representations (i.e., hashes).
std::unordered_map<const T*, p_hash_type> map;
std::unordered_map<const T*, std::shared_ptr<CPP_InitInfo>> gi_s;
// Maps internal representations to distinct values.
std::unordered_map<p_hash_type, int> map2;
// Tracks the set of distinct keys, to facilitate iterating over them.
// Each such key also has an entry in map2.
std::vector<IntrusivePtr<T>> keys;
// Maps internal representations back to keys.
std::unordered_map<p_hash_type, const T*> reps;
// Used to construct key names.
std::string base_name;
// Whether to base the names out of a single global, or distinct
// globals.
bool single_global;
};
} // zeek::detail