1 /** 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef _PANDA_VERIFIER_CACHE_FILE_ENTITY_CACHE_H__ 17 #define _PANDA_VERIFIER_CACHE_FILE_ENTITY_CACHE_H__ 18 19 #include "macros.h" 20 21 #include "verification/util/hash.h" 22 #include "verification/util/optional_ref.h" 23 24 #include "libpandafile/file.h" 25 26 #include "runtime/include/mem/panda_containers.h" 27 28 #include <cstdint> 29 #include <tuple> 30 #include <type_traits> 31 32 namespace panda::verifier { 33 34 using TypeIndexT = uint8_t; 35 36 template <typename... Types> 37 constexpr TypeIndexT TypeIndex = []() { 38 static_assert(sizeof...(Types) > 1, "Type was not found in list"); 39 return 0; 40 }(); 41 42 template <typename T, typename... Types> 43 constexpr TypeIndexT TypeIndex<T, T, Types...> = 0; 44 45 template <typename T, typename U, typename... Types> 46 constexpr TypeIndexT TypeIndex<T, U, Types...> = []() { 47 constexpr TypeIndexT result = 1 + TypeIndex<T, Types...>; 48 static_assert(result != 0, "Overflow! TypeIndex used with more than 255 arguments"); 49 return result; 50 }(); 51 52 template <typename... CachedTypes> 53 class FileEntityCache { 54 using FileId = uint64_t; 55 using Key = std::tuple<FileId, panda_file::File::EntityId, TypeIndexT>; 56 57 template <typename Entity> GetKey(const panda_file::File & pf,panda_file::File::EntityId id)58 Key GetKey(const panda_file::File &pf, panda_file::File::EntityId id) 59 { 60 return {pf.GetUniqId(), id, TypeIndex<Entity, CachedTypes...>}; 61 } 62 63 public: 64 template <typename Entity> GetCached(const panda_file::File & pf,panda_file::File::EntityId id)65 OptionalRef<Entity> GetCached(const panda_file::File &pf, panda_file::File::EntityId id) 66 { 67 const auto it = storage.find(GetKey<Entity>(pf, id)); 68 if (it != storage.cend()) { 69 return *static_cast<Entity *>(it->second); 70 } 71 return {}; 72 } 73 74 template <typename Entity> AddToCache(const panda_file::File & pf,panda_file::File::EntityId id,Entity & entity)75 void AddToCache(const panda_file::File &pf, panda_file::File::EntityId id, Entity &entity) 76 { 77 storage.insert_or_assign(GetKey<Entity>(pf, id), &entity); 78 } 79 80 private: 81 PandaUnorderedMap<Key, void *> storage; 82 }; 83 84 } // namespace panda::verifier 85 86 #endif // !_PANDA_VERIFIER_CACHE_FILE_ENTITY_CACHE_H__ 87