From eaf6b944033dd186da1347c25fa7d713681cedb9 Mon Sep 17 00:00:00 2001 From: danakj Date: Fri, 31 Oct 2025 15:51:30 -0400 Subject: [PATCH] get-raw-index --- toolchain/base/canonical_value_store.h | 6 ++++-- toolchain/base/relational_value_store.h | 14 +++++++------ toolchain/base/value_store.h | 27 +++++++++++++++---------- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/toolchain/base/canonical_value_store.h b/toolchain/base/canonical_value_store.h index 61531002adec2..fea0f12008081 100644 --- a/toolchain/base/canonical_value_store.h +++ b/toolchain/base/canonical_value_store.h @@ -69,9 +69,11 @@ class CanonicalValueStore { mem_usage.Add(MemUsage::ConcatLabel(label, "set_"), bytes, bytes); } - auto GetRawIndex(IdT id) const -> int32_t { return values_.GetRawIndex(id); } - auto GetIdTag() const -> IdTag { return values_.GetIdTag(); } + auto GetRawIndex(IdT id) const -> int32_t { return values_.GetRawIndex(id); } + auto TryGetRawIndex(IdT id) const -> int32_t { + return values_.TryGetRawIndex(id); + } private: class KeyContext; diff --git a/toolchain/base/relational_value_store.h b/toolchain/base/relational_value_store.h index 8d96609548008..bec29acce04f0 100644 --- a/toolchain/base/relational_value_store.h +++ b/toolchain/base/relational_value_store.h @@ -26,7 +26,7 @@ namespace Carbon { // // When adding to the store, the user provides the related // `RelatedStoreT::IdType` along with the value being stored, and gets back the -// ID of the value in the store. +// ID of the value in the store. The ids share an IdTag with the related store. // // This store requires more storage space than normal ValueStore does, as it // requires storing a bit for presence of each `RelatedStore::IdType`. And it @@ -45,7 +45,8 @@ class RelationalValueStore { // Given the related ID and a value, stores the value and returns a mapped ID // to reference it in the store. auto Add(RelatedIdType related_id, ValueType value) -> IdT { - auto related_index = related_store_->GetRawIndex(related_id); + auto related_index = related_store_->TryGetRawIndex(related_id); + CARBON_DCHECK(related_index >= 0, "{0}", related_id); if (static_cast(related_index) >= values_.size()) { values_.resize(related_index + 1); } @@ -53,13 +54,14 @@ class RelationalValueStore { CARBON_CHECK(!opt.has_value(), "Add with `related_id` that was already added to the store"); opt.emplace(std::move(value)); - return IdT(related_store_->GetIdTag().Apply(related_index)); + return IdT(related_id.index); } // Returns the ID of a value in the store if the `related_id` was previously // used to add a value to the store, or None. auto TryGetId(RelatedIdType related_id) const -> IdT { - auto related_index = related_store_->GetRawIndex(related_id); + auto related_index = related_store_->TryGetRawIndex(related_id); + CARBON_DCHECK(related_index >= 0, "{0}", related_id); if (static_cast(related_index) >= values_.size()) { return IdT::None; } @@ -67,12 +69,12 @@ class RelationalValueStore { if (!opt.has_value()) { return IdT::None; } - return IdT(related_store_->GetIdTag().Apply(related_index)); + return IdT(related_id.index); } // Returns a value for an ID. auto Get(IdT id) const -> ConstRefType { - auto index = related_store_->GetIdTag().Remove(id.index); + auto index = related_store_->TryGetRawIndex(RelatedIdType(id.index)); CARBON_DCHECK(index >= 0, "{0}", id); return *values_[index]; } diff --git a/toolchain/base/value_store.h b/toolchain/base/value_store.h index f75b2fb852ca5..4568e84520309 100644 --- a/toolchain/base/value_store.h +++ b/toolchain/base/value_store.h @@ -209,15 +209,17 @@ class ValueStore // Returns a mutable value for an ID. auto Get(IdType id) -> RefType { - CARBON_DCHECK(id.index >= 0, "{0}", id); - auto [chunk_index, pos] = IdToChunkIndices(id); + auto raw_index = TryGetRawIndex(id); + CARBON_DCHECK(raw_index >= 0, "{0}", id); + auto [chunk_index, pos] = RawIndexToChunkIndices(raw_index); return chunks_[chunk_index].Get(pos); } // Returns the value for an ID. auto Get(IdType id) const -> ConstRefType { - CARBON_DCHECK(id.index >= 0, "{0}", id); - auto [chunk_index, pos] = IdToChunkIndices(id); + auto raw_index = TryGetRawIndex(id); + CARBON_DCHECK(raw_index >= 0, "{0}", id); + auto [chunk_index, pos] = RawIndexToChunkIndices(raw_index); return chunks_[chunk_index].Get(pos); } @@ -310,9 +312,18 @@ class ValueStore } auto GetIdTag() const -> IdTag { return tag_; } + // Removes the IdTag from the `id` and returns the absolute index into the + // store. Not valid to call for negative values, which are not part of the + // store. auto GetRawIndex(IdT id) const -> int32_t { + auto index = TryGetRawIndex(id); + CARBON_DCHECK(index >= 0); + return index; + } + // Like GetRawIndex() but accepts negative values like `None` and passes them + // through, even though they would not be a valid index into an array. + auto TryGetRawIndex(IdT id) const -> int32_t { auto index = tag_.Remove(id.index); - CARBON_DCHECK(index >= 0, "{0}", index); #ifndef NDEBUG if (index >= size_) { // Attempt to decompose id.index to include extra detail in the check @@ -470,12 +481,6 @@ class ValueStore return {chunk, pos}; } - // Converts an id into an index into the set of chunks, and an offset into - // that specific chunk. - auto IdToChunkIndices(IdType id) const -> std::pair { - return RawIndexToChunkIndices(GetRawIndex(id)); - } - // Number of elements added to the store. The number should never exceed what // fits in an `int32_t`, which is checked in non-optimized builds in Add(). int32_t size_ = 0;