Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Refactor TypeFactory, TypeCache, and ValueCache #477

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
1 commit merged into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 23 additions & 158 deletions common/type_factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,17 @@

#include "common/type_factory.h"

#include <utility>

#include "absl/base/attributes.h"
#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_map.h"
#include "absl/log/absl_check.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "absl/types/optional.h"
#include "common/casting.h"
#include "common/memory.h"
#include "common/sized_input_view.h"
#include "common/type.h"
#include "common/type_kind.h"
#include "common/types/thread_compatible_type_factory.h"
#include "common/types/thread_safe_type_factory.h"
#include "common/types/type_cache.h"
#include "internal/names.h"

Expand All @@ -38,158 +35,8 @@ namespace {
using common_internal::ListTypeCacheMap;
using common_internal::MapTypeCacheMap;
using common_internal::OpaqueTypeCacheMap;
using common_internal::OpaqueTypeKey;
using common_internal::OpaqueTypeKeyView;
using common_internal::ProcessLocalTypeCache;

using StructTypeCacheMap = absl::flat_hash_map<absl::string_view, StructType>;

class ThreadCompatibleTypeFactory final : public TypeFactory {
public:
explicit ThreadCompatibleTypeFactory(MemoryManagerRef memory_manager)
: memory_manager_(memory_manager) {}

MemoryManagerRef memory_manager() const override { return memory_manager_; }

ListType CreateListTypeImpl(TypeView element) override {
if (auto list_type = list_types_.find(element);
list_type != list_types_.end()) {
return list_type->second;
}
ListType list_type(memory_manager(), Type(element));
return list_types_.insert({list_type.element(), list_type}).first->second;
}

MapType CreateMapTypeImpl(TypeView key, TypeView value) override {
if (auto map_type = map_types_.find(std::make_pair(key, value));
map_type != map_types_.end()) {
return map_type->second;
}
MapType map_type(memory_manager(), Type(key), Type(value));
return map_types_
.insert({std::make_pair(map_type.key(), map_type.value()), map_type})
.first->second;
}

StructType CreateStructTypeImpl(absl::string_view name) override {
if (auto struct_type = struct_types_.find(name);
struct_type != struct_types_.end()) {
return struct_type->second;
}
StructType struct_type(memory_manager(), name);
return struct_types_.insert({struct_type.name(), struct_type})
.first->second;
}

OpaqueType CreateOpaqueTypeImpl(
absl::string_view name,
const SizedInputView<TypeView>& parameters) override {
if (auto opaque_type = opaque_types_.find(
OpaqueTypeKeyView{.name = name, .parameters = parameters});
opaque_type != opaque_types_.end()) {
return opaque_type->second;
}
OpaqueType opaque_type(memory_manager(), name, parameters);
return opaque_types_
.insert({OpaqueTypeKey{.name = opaque_type.name(),
.parameters = opaque_type.parameters()},
opaque_type})
.first->second;
}

private:
MemoryManagerRef memory_manager_;
ListTypeCacheMap list_types_;
MapTypeCacheMap map_types_;
StructTypeCacheMap struct_types_;
OpaqueTypeCacheMap opaque_types_;
};

class ThreadSafeTypeFactory final : public TypeFactory {
public:
explicit ThreadSafeTypeFactory(MemoryManagerRef memory_manager)
: memory_manager_(memory_manager) {}

MemoryManagerRef memory_manager() const override { return memory_manager_; }

ListType CreateListTypeImpl(TypeView element) override {
{
absl::ReaderMutexLock lock(&list_types_mutex_);
if (auto list_type = list_types_.find(element);
list_type != list_types_.end()) {
return list_type->second;
}
}
ListType list_type(memory_manager(), Type(element));
absl::WriterMutexLock lock(&list_types_mutex_);
return list_types_.insert({list_type.element(), list_type}).first->second;
}

MapType CreateMapTypeImpl(TypeView key, TypeView value) override {
{
absl::ReaderMutexLock lock(&map_types_mutex_);
if (auto map_type = map_types_.find(std::make_pair(key, value));
map_type != map_types_.end()) {
return map_type->second;
}
}
MapType map_type(memory_manager(), Type(key), Type(value));
absl::WriterMutexLock lock(&map_types_mutex_);
return map_types_
.insert({std::make_pair(map_type.key(), map_type.value()), map_type})
.first->second;
}

StructType CreateStructTypeImpl(absl::string_view name) override {
{
absl::ReaderMutexLock lock(&struct_types_mutex_);
if (auto struct_type = struct_types_.find(name);
struct_type != struct_types_.end()) {
return struct_type->second;
}
}
StructType struct_type(memory_manager(), name);
absl::WriterMutexLock lock(&struct_types_mutex_);
return struct_types_.insert({struct_type.name(), struct_type})
.first->second;
}

OpaqueType CreateOpaqueTypeImpl(
absl::string_view name,
const SizedInputView<TypeView>& parameters) override {
if (auto opaque_type =
ProcessLocalTypeCache::Get()->FindOpaqueType(name, parameters);
opaque_type.has_value()) {
return OpaqueType(*opaque_type);
}
{
absl::ReaderMutexLock lock(&opaque_types_mutex_);
if (auto opaque_type = opaque_types_.find(
OpaqueTypeKeyView{.name = name, .parameters = parameters});
opaque_type != opaque_types_.end()) {
return opaque_type->second;
}
}
OpaqueType opaque_type(memory_manager(), name, parameters);
absl::WriterMutexLock lock(&opaque_types_mutex_);
return opaque_types_
.insert({OpaqueTypeKey{.name = opaque_type.name(),
.parameters = opaque_type.parameters()},
opaque_type})
.first->second;
}

private:
MemoryManagerRef memory_manager_;
mutable absl::Mutex list_types_mutex_;
ListTypeCacheMap list_types_ ABSL_GUARDED_BY(list_types_mutex_);
mutable absl::Mutex map_types_mutex_;
MapTypeCacheMap map_types_ ABSL_GUARDED_BY(map_types_mutex_);
mutable absl::Mutex struct_types_mutex_;
StructTypeCacheMap struct_types_ ABSL_GUARDED_BY(struct_types_mutex_);
mutable absl::Mutex opaque_types_mutex_;
OpaqueTypeCacheMap opaque_types_ ABSL_GUARDED_BY(opaque_types_mutex_);
};
using common_internal::StructTypeCacheMap;

bool IsValidMapKeyType(TypeView type) {
switch (type.kind()) {
Expand Down Expand Up @@ -249,13 +96,31 @@ OptionalType TypeFactory::CreateOptionalType(TypeView parameter) {
return Cast<OptionalType>(CreateOpaqueType(OptionalType::kName, {parameter}));
}

ListTypeView TypeFactory::GetDynListType() {
return ProcessLocalTypeCache::Get()->GetDynListType();
}

MapTypeView TypeFactory::GetDynDynMapType() {
return ProcessLocalTypeCache::Get()->GetDynDynMapType();
}

MapTypeView TypeFactory::GetStringDynMapType() {
return ProcessLocalTypeCache::Get()->GetStringDynMapType();
}

OptionalTypeView TypeFactory::GetDynOptionalType() {
return ProcessLocalTypeCache::Get()->GetDynOptionalType();
}

Shared<TypeFactory> NewThreadCompatibleTypeFactory(
MemoryManagerRef memory_manager) {
return memory_manager.MakeShared<ThreadCompatibleTypeFactory>(memory_manager);
return memory_manager
.MakeShared<common_internal::ThreadCompatibleTypeFactory>(memory_manager);
}

Shared<TypeFactory> NewThreadSafeTypeFactory(MemoryManagerRef memory_manager) {
return memory_manager.MakeShared<ThreadSafeTypeFactory>(memory_manager);
return memory_manager.MakeShared<common_internal::ThreadSafeTypeFactory>(
memory_manager);
}

} // namespace cel
13 changes: 13 additions & 0 deletions common/type_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,19 @@ class TypeFactory {
// Creates a `OptionalType`.
OptionalType CreateOptionalType(TypeView parameter);

// `GetDynListType` gets a view of the `ListType` type `list(dyn)`.
ListTypeView GetDynListType();

// `GetDynDynMapType` gets a view of the `MapType` type `map(dyn, dyn)`.
MapTypeView GetDynDynMapType();

// `GetDynDynMapType` gets a view of the `MapType` type `map(string, dyn)`.
MapTypeView GetStringDynMapType();

// `GetDynOptionalType` gets a view of the `OptionalType` type
// `optional(dyn)`.
OptionalTypeView GetDynOptionalType();

private:
virtual ListType CreateListTypeImpl(TypeView element) = 0;

Expand Down
72 changes: 72 additions & 0 deletions common/types/thread_compatible_type_factory.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "common/types/thread_compatible_type_factory.h"

#include <utility>

#include "absl/strings/string_view.h"
#include "common/sized_input_view.h"
#include "common/type.h"
#include "common/types/type_cache.h"

namespace cel::common_internal {

ListType ThreadCompatibleTypeFactory::CreateListTypeImpl(TypeView element) {
if (auto list_type = list_types_.find(element);
list_type != list_types_.end()) {
return list_type->second;
}
ListType list_type(memory_manager(), Type(element));
return list_types_.insert({list_type.element(), list_type}).first->second;
}

MapType ThreadCompatibleTypeFactory::CreateMapTypeImpl(TypeView key,
TypeView value) {
if (auto map_type = map_types_.find(std::make_pair(key, value));
map_type != map_types_.end()) {
return map_type->second;
}
MapType map_type(memory_manager(), Type(key), Type(value));
return map_types_
.insert({std::make_pair(map_type.key(), map_type.value()), map_type})
.first->second;
}

StructType ThreadCompatibleTypeFactory::CreateStructTypeImpl(
absl::string_view name) {
if (auto struct_type = struct_types_.find(name);
struct_type != struct_types_.end()) {
return struct_type->second;
}
StructType struct_type(memory_manager(), name);
return struct_types_.insert({struct_type.name(), struct_type}).first->second;
}

OpaqueType ThreadCompatibleTypeFactory::CreateOpaqueTypeImpl(
absl::string_view name, const SizedInputView<TypeView>& parameters) {
if (auto opaque_type = opaque_types_.find(
OpaqueTypeKeyView{.name = name, .parameters = parameters});
opaque_type != opaque_types_.end()) {
return opaque_type->second;
}
OpaqueType opaque_type(memory_manager(), name, parameters);
return opaque_types_
.insert({OpaqueTypeKey{.name = opaque_type.name(),
.parameters = opaque_type.parameters()},
opaque_type})
.first->second;
}

} // namespace cel::common_internal
56 changes: 56 additions & 0 deletions common/types/thread_compatible_type_factory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// IWYU pragma: private

#ifndef THIRD_PARTY_CEL_CPP_COMMON_TYPES_THREAD_COMPATIBLE_TYPE_FACTORY_H_
#define THIRD_PARTY_CEL_CPP_COMMON_TYPES_THREAD_COMPATIBLE_TYPE_FACTORY_H_

#include "absl/strings/string_view.h"
#include "common/memory.h"
#include "common/sized_input_view.h"
#include "common/type.h"
#include "common/type_factory.h"
#include "common/types/type_cache.h"

namespace cel::common_internal {

class ThreadCompatibleTypeFactory final : public TypeFactory {
public:
explicit ThreadCompatibleTypeFactory(MemoryManagerRef memory_manager)
: memory_manager_(memory_manager) {}

MemoryManagerRef memory_manager() const override { return memory_manager_; }

private:
ListType CreateListTypeImpl(TypeView element) override;

MapType CreateMapTypeImpl(TypeView key, TypeView value) override;

StructType CreateStructTypeImpl(absl::string_view name) override;

OpaqueType CreateOpaqueTypeImpl(
absl::string_view name,
const SizedInputView<TypeView>& parameters) override;

MemoryManagerRef memory_manager_;
ListTypeCacheMap list_types_;
MapTypeCacheMap map_types_;
StructTypeCacheMap struct_types_;
OpaqueTypeCacheMap opaque_types_;
};

} // namespace cel::common_internal

#endif // THIRD_PARTY_CEL_CPP_COMMON_TYPES_THREAD_COMPATIBLE_TYPE_FACTORY_H_
Loading