@@ -20,10 +20,13 @@ limitations under the License.
2020#include < string>
2121#include < string_view>
2222
23+ #include " absl/algorithm/container.h"
2324#include " absl/base/attributes.h"
2425#include " absl/base/const_init.h"
2526#include " absl/container/flat_hash_map.h"
27+ #include " absl/status/status.h"
2628#include " absl/status/statusor.h"
29+ #include " absl/strings/string_view.h"
2730#include " absl/synchronization/mutex.h"
2831#include " xla/util.h"
2932
@@ -39,24 +42,56 @@ static ExternalTypeIdRegistry& StaticExternalTypeIdRegistry() {
3942 return *registry;
4043}
4144
42- TypeIdRegistry::TypeId TypeIdRegistry::GetNextTypeId () {
45+ TypeIdRegistry::TypeId TypeIdRegistry::GetNextInternalTypeId () {
4346 static auto * counter = new std::atomic<int64_t >(1 );
4447 return TypeId (counter->fetch_add (1 ));
4548}
4649
47- absl::StatusOr<TypeIdRegistry::TypeId> TypeIdRegistry::RegisterExternalTypeId (
50+ TypeIdRegistry::TypeId TypeIdRegistry::GetNextExternalTypeId () {
51+ static auto * counter = new std::atomic<int64_t >(1 );
52+ return TypeId (counter->fetch_add (1 ));
53+ }
54+
55+ absl::StatusOr<TypeIdRegistry::TypeId> TypeIdRegistry::AssignExternalTypeId (
4856 std::string_view name) {
4957 absl::MutexLock lock (&type_registry_mutex);
5058 auto & registry = StaticExternalTypeIdRegistry ();
5159
52- // Try to emplace with type id zero and fill it with real type id only if we
60+ // Try to emplace with unknow type id and fill it with real type id only if we
5361 // successfully acquired an entry for a given name.
54- auto emplaced = registry.emplace (name, TypeId ( 0 ) );
62+ auto emplaced = registry.emplace (name, kUnknownTypeId );
5563 if (!emplaced.second ) {
56- return Internal (" Type id %d already registered for type name %s " ,
57- emplaced.first ->second .value (), name );
64+ return Internal (" Type name %s already registered with type id %d " , name ,
65+ emplaced.first ->second .value ());
5866 }
59- return emplaced.first ->second = GetNextTypeId ();
67+
68+ // Returns true if the registry contains an entry with a given type id.
69+ auto type_id_is_in_use = [®istry](TypeId type_id) {
70+ return absl::c_any_of (registry,
71+ [&](const auto & e) { return e.second == type_id; });
72+ };
73+
74+ // Create a new type id that is not already in use.
75+ TypeId type_id = GetNextExternalTypeId ();
76+ while (type_id_is_in_use (type_id)) {
77+ type_id = GetNextExternalTypeId ();
78+ }
79+
80+ return emplaced.first ->second = type_id;
81+ }
82+
83+ absl::Status TypeIdRegistry::RegisterExternalTypeId (absl::string_view name,
84+ TypeId type_id) {
85+ absl::MutexLock lock (&type_registry_mutex);
86+ auto & registry = StaticExternalTypeIdRegistry ();
87+
88+ auto emplaced = registry.emplace (name, type_id);
89+ if (!emplaced.second && emplaced.first ->second != type_id) {
90+ return Internal (" Type name %s already registered with type id %d vs %d)" ,
91+ name, emplaced.first ->second .value (), type_id.value ());
92+ }
93+
94+ return absl::OkStatus ();
6095}
6196
6297} // namespace xla::ffi
0 commit comments