-
Notifications
You must be signed in to change notification settings - Fork 5.3k
stats: remove symbol table interface #19597
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
Merged
jmarantz
merged 13 commits into
envoyproxy:main
from
jmarantz:symbol-table-remove-interface
Feb 2, 2022
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
38c6fea
remove the symbol-table interface and use the impl directly.
jmarantz 8a0d64a
Put forward declarations into the interface file.
jmarantz 20b6303
remove now-extraneous dependency on interface (which is now just forw…
jmarantz 9d40d7f
include-what-you-use and remove extraneous ref to cstring.
jmarantz e7ce24a
Rename SymbolTableImpl to SymbolTable in the impl file itself.
jmarantz f01dc17
Merge branch 'main' into symbol-table-remove-interface
jmarantz e16df0f
remove comment that was originally in the interface that no longer m…
jmarantz 43afeff
Merge branch 'main' into symbol-table-remove-interface
jmarantz a7074e2
fix doc and restore API comments
jmarantz e4a3105
Merge branch 'main' into symbol-table-remove-interface
jmarantz 0b19f39
minor cleanups
jmarantz 9aed496
clean up .bazelversion
jmarantz 44ee0cf
fix comment
jmarantz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,249 +1,22 @@ | ||
| #pragma once | ||
|
|
||
| #include <functional> | ||
| #include <memory> | ||
| #include <utility> | ||
| #include <vector> | ||
|
|
||
| #include "envoy/common/pure.h" | ||
|
|
||
| #include "absl/container/inlined_vector.h" | ||
| #include "absl/strings/string_view.h" | ||
|
|
||
| namespace Envoy { | ||
| namespace Stats { | ||
|
|
||
| /** | ||
| * Runtime representation of an encoded stat name. This is predeclared only in | ||
| * the interface without abstract methods, because (a) the underlying class | ||
| * representation is common to both implementations of SymbolTable, and (b) | ||
| * we do not want or need the overhead of a vptr per StatName. The common | ||
| * declaration for StatName is in source/common/stats/symbol_table_impl.h | ||
| */ | ||
| class StatName; | ||
| using StatNameVec = absl::InlinedVector<StatName, 8>; | ||
|
|
||
| class StatNameList; | ||
| class StatNameSet; | ||
|
|
||
| using StatNameSetPtr = std::unique_ptr<StatNameSet>; | ||
| // Forward declarations for the symbol table classes. See | ||
| // source/common/stats/symbol_table_impl.h" for the class definitions. | ||
| // | ||
| // TODO(jmarantz): remove this file and put the forward declarations into stats.h. | ||
|
|
||
| /** | ||
| * Holds a range of indexes indicating which parts of a stat-name are | ||
| * dynamic. This is used to transfer stats from hot-restart parent to child, | ||
| * retaining the same name structure. | ||
| * Runtime representation of an encoded stat name. | ||
| */ | ||
| using DynamicSpan = std::pair<uint32_t, uint32_t>; | ||
| using DynamicSpans = std::vector<DynamicSpan>; | ||
| class StatName; | ||
|
|
||
| /** | ||
| * SymbolTable manages a namespace optimized for stat names, exploiting their | ||
| * typical composition from "."-separated tokens, with a significant overlap | ||
| * between the tokens. The interface is designed to balance optimal storage | ||
| * at scale with hiding details from users. We seek to provide the most abstract | ||
| * interface possible that avoids adding per-stat overhead or taking locks in | ||
| * the hot path. | ||
| * Holds a set of symbols used to compose hierarhical names. | ||
| */ | ||
| class SymbolTable { | ||
| public: | ||
| /** | ||
| * Efficient byte-encoded storage of an array of tokens. The most common | ||
| * tokens are typically < 127, and are represented directly. tokens >= 128 | ||
| * spill into the next byte, allowing for tokens of arbitrary numeric value to | ||
| * be stored. As long as the most common tokens are low-valued, the | ||
| * representation is space-efficient. This scheme is similar to UTF-8. The | ||
| * token ordering is dependent on the order in which stat-names are encoded | ||
| * into the SymbolTable, which will not be optimal, but in practice appears | ||
| * to be pretty good. | ||
| * | ||
| * This is exposed in the interface for the benefit of join(), which is | ||
| * used in the hot-path to append two stat-names into a temp without taking | ||
| * locks. This is used then in thread-local cache lookup, so that once warm, | ||
| * no locks are taken when looking up stats. | ||
| */ | ||
| using Storage = uint8_t[]; | ||
| using StoragePtr = std::unique_ptr<Storage>; | ||
|
|
||
| virtual ~SymbolTable() = default; | ||
|
|
||
| /** | ||
| * @return uint64_t the number of symbols in the symbol table. | ||
| */ | ||
| virtual uint64_t numSymbols() const PURE; | ||
|
|
||
| /** | ||
| * Decodes a vector of symbols back into its period-delimited stat name. If | ||
| * decoding fails on any part of the symbol_vec, we release_assert and crash, | ||
| * since this should never happen, and we don't want to continue running | ||
| * with a corrupt stats set. | ||
| * | ||
| * @param stat_name the stat name. | ||
| * @return std::string stringified stat_name. | ||
| */ | ||
| virtual std::string toString(const StatName& stat_name) const PURE; | ||
|
|
||
| /** | ||
| * Determines whether one StatName lexically precedes another. Note that | ||
| * the lexical order may not exactly match the lexical order of the | ||
| * elaborated strings. For example, stat-name of "-.-" would lexically | ||
| * sort after "---" but when encoded as a StatName would come lexically | ||
| * earlier. In practice this is unlikely to matter as those are not | ||
| * reasonable names for Envoy stats. | ||
| * | ||
| * Note that this operation has to be performed with the context of the | ||
| * SymbolTable so that the individual Symbol objects can be converted | ||
| * into strings for lexical comparison. | ||
| * | ||
| * @param a the first stat name | ||
| * @param b the second stat name | ||
| * @return bool true if a lexically precedes b. | ||
| */ | ||
| virtual bool lessThan(const StatName& a, const StatName& b) const PURE; | ||
| virtual bool lessThanLockHeld(const StatName& a, const StatName& b) const PURE; | ||
|
|
||
| /** | ||
| * Joins two or more StatNames. For example if we have StatNames for {"a.b", | ||
| * "c.d", "e.f"} then the joined stat-name matches "a.b.c.d.e.f". The | ||
| * advantage of using this representation is that it avoids having to | ||
| * decode/encode into the elaborated form, and does not require locking the | ||
| * SymbolTable. | ||
| * | ||
| * Note that this method does not bump reference counts on the referenced | ||
| * Symbols in the SymbolTable, so it's only valid as long for the lifetime of | ||
| * the joined StatNames. | ||
| * | ||
| * This is intended for use doing cached name lookups of scoped stats, where | ||
| * the scope prefix and the names to combine it with are already in StatName | ||
| * form. Using this class, they can be combined without accessing the | ||
| * SymbolTable or, in particular, taking its lock. | ||
| * | ||
| * @param stat_names the names to join. | ||
| * @return Storage allocated for the joined name. | ||
| */ | ||
| virtual StoragePtr join(const StatNameVec& stat_names) const PURE; | ||
|
|
||
| /** | ||
| * Populates a StatNameList from a list of encodings. This is not done at | ||
| * construction time to enable StatNameList to be instantiated directly in | ||
| * a class that doesn't have a live SymbolTable when it is constructed. | ||
| * | ||
| * @param names A pointer to the first name in an array, allocated by the caller. | ||
| * @param num_names The number of names. | ||
| * @param list The StatNameList representing the stat names. | ||
| */ | ||
| virtual void populateList(const StatName* names, uint32_t num_names, StatNameList& list) PURE; | ||
|
|
||
| #ifndef ENVOY_CONFIG_COVERAGE | ||
| virtual void debugPrint() const PURE; | ||
| #endif | ||
|
|
||
| using RecentLookupsFn = std::function<void(absl::string_view, uint64_t)>; | ||
|
|
||
| /** | ||
| * Calls the provided function with the name of the most recently looked-up | ||
| * symbols, including lookups on any StatNameSets, and with a count of | ||
| * the recent lookups on that symbol. | ||
| * | ||
| * @param iter the function to call for every recent item. | ||
| */ | ||
| virtual uint64_t getRecentLookups(const RecentLookupsFn& iter) const PURE; | ||
|
|
||
| /** | ||
| * Clears the recent-lookups structures. | ||
| */ | ||
| virtual void clearRecentLookups() PURE; | ||
|
|
||
| /** | ||
| * Sets the recent-lookup capacity. | ||
| */ | ||
| virtual void setRecentLookupCapacity(uint64_t capacity) PURE; | ||
|
|
||
| /** | ||
| * @return The configured recent-lookup tracking capacity. | ||
| */ | ||
| virtual uint64_t recentLookupCapacity() const PURE; | ||
|
|
||
| /** | ||
| * Creates a StatNameSet. | ||
| * | ||
| * @param name the name of the set. | ||
| * @return the set. | ||
| */ | ||
| virtual StatNameSetPtr makeSet(absl::string_view name) PURE; | ||
|
|
||
| /** | ||
| * Identifies the dynamic components of a stat_name into an array of integer | ||
| * pairs, indicating the begin/end of spans of tokens in the stat-name that | ||
| * are created from StatNameDynamicStore or StatNameDynamicPool. | ||
| * | ||
| * This can be used to reconstruct the same exact StatNames in | ||
| * StatNames::mergeStats(), to enable stat continuity across hot-restart. | ||
| * | ||
| * @param stat_name the input stat name. | ||
| * @return the array of pairs indicating the bounds. | ||
| */ | ||
| virtual DynamicSpans getDynamicSpans(StatName stat_name) const PURE; | ||
|
|
||
| /** | ||
| * Calls a function with the symbol table's lock held. This is needed | ||
| * for sortByStatName to avoid taking a lock on each comparison. | ||
| * | ||
| * TODO(jmarantz): This indirection can likely be removed once SymbolTable | ||
| * is changed from an interface to a concrete implementation. The interface | ||
| * was only longer needed during construction to allow for a fake symbol | ||
| * table implementation to be used by default and controlled by flag. | ||
| * | ||
| * @param fn a function to be called once the lock ahs been acquired. | ||
| */ | ||
| virtual void withLockHeld(std::function<void()> fn) const PURE; | ||
|
|
||
| private: | ||
| friend struct HeapStatData; | ||
| friend class StatNameDynamicStorage; | ||
| friend class StatNameStorage; | ||
| friend class StatNameList; | ||
| friend class StatNameSet; | ||
|
|
||
| // The following methods are private, but are called by friend classes | ||
| // StatNameStorage and StatNameList, which must be friendly with SymbolTable | ||
| // in order to manage the reference-counted symbols they own. | ||
|
|
||
| /** | ||
| * Since SymbolTable does manual reference counting, a client of SymbolTable | ||
| * must manually call free(symbol_vec) when it is freeing the backing store | ||
| * for a StatName. This way, the symbol table will grow and shrink | ||
| * dynamically, instead of being write-only. | ||
| * | ||
| * @param stat_name the stat name. | ||
| */ | ||
| virtual void free(const StatName& stat_name) PURE; | ||
|
|
||
| /** | ||
| * StatName backing-store can be managed by callers in a variety of ways | ||
| * to minimize overhead. But any persistent reference to a StatName needs | ||
| * to hold onto its own reference-counts for all symbols. This method | ||
| * helps callers ensure the symbol-storage is maintained for the lifetime | ||
| * of a reference. | ||
| * | ||
| * @param stat_name the stat name. | ||
| */ | ||
| virtual void incRefCount(const StatName& stat_name) PURE; | ||
|
|
||
| /** | ||
| * Encodes 'name' into the symbol table. Bumps reference counts for referenced | ||
| * symbols. The caller must manage the storage, and is responsible for calling | ||
| * SymbolTable::free() to release the reference counts. | ||
| * | ||
| * @param name The name to encode. | ||
| * @return The encoded name, transferring ownership to the caller. | ||
| * | ||
| */ | ||
| virtual StoragePtr encode(absl::string_view name) PURE; | ||
|
|
||
| virtual StoragePtr makeDynamicStorage(absl::string_view name) PURE; | ||
| }; | ||
|
|
||
| using SymbolTablePtr = std::unique_ptr<SymbolTable>; | ||
| class SymbolTable; | ||
|
|
||
| } // namespace Stats | ||
| } // namespace Envoy | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.