1 // Copyright (C) 2022 Google LLC 2 // 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 #ifndef ICING_STORE_KEY_MAPPER_H_ 16 #define ICING_STORE_KEY_MAPPER_H_ 17 18 #include <cstdint> 19 #include <cstring> 20 #include <string> 21 #include <string_view> 22 #include <type_traits> 23 #include <unordered_map> 24 25 #include "icing/text_classifier/lib3/utils/base/status.h" 26 #include "icing/text_classifier/lib3/utils/base/statusor.h" 27 #include "icing/absl_ports/str_join.h" 28 #include "icing/util/crc32.h" 29 30 namespace icing { 31 namespace lib { 32 33 // An interface for file-backed mapping between the string key and a trivially 34 // copyable value type. 35 // 36 // The implementation for KeyMapper should be thread-compatible 37 template <typename T, typename Formatter = absl_ports::DefaultFormatter> 38 class KeyMapper { 39 public: 40 class Iterator { 41 public: 42 virtual ~Iterator() = default; 43 44 // Advance to the next entry. 45 // 46 // Returns: 47 // True on success, otherwise false. 48 virtual bool Advance() = 0; 49 50 // Get the key. 51 // 52 // REQUIRES: The preceding call for Advance() is true. 53 virtual std::string_view GetKey() const = 0; 54 55 // Get the value. 56 // 57 // REQUIRES: The preceding call for Advance() is true. 58 virtual T GetValue() const = 0; 59 }; 60 61 virtual ~KeyMapper() = default; 62 63 // Inserts/Updates value for key. 64 // Returns any encountered IO errors. 65 // 66 // NOTE: Put() doesn't automatically flush changes to disk and relies on 67 // either explicit calls to PersistToDisk() or a clean shutdown of the class. 68 virtual libtextclassifier3::Status Put(std::string_view key, T value) = 0; 69 70 // Finds the current value for key and returns it. If key is not present, it 71 // is inserted with next_value and next_value is returned. 72 // 73 // Returns any IO errors that may occur during Put. 74 virtual libtextclassifier3::StatusOr<T> GetOrPut(std::string_view key, 75 T next_value) = 0; 76 77 // Returns the value corresponding to the key. 78 // 79 // Returns NOT_FOUND error if the key was missing. 80 // Returns any encountered IO errors. 81 virtual libtextclassifier3::StatusOr<T> Get(std::string_view key) const = 0; 82 83 // Deletes data related to the given key. Returns true on success. 84 virtual bool Delete(std::string_view key) = 0; 85 86 // Returns an iterator of the key mapper. 87 // 88 // Example usage: 89 // auto itr = key_mapper->GetIterator(); 90 // while (itr->Advance()) { 91 // std::cout << itr->GetKey() << " " << itr->GetValue() << std::endl; 92 // } 93 virtual std::unique_ptr<Iterator> GetIterator() const = 0; 94 95 // Count of unique keys stored in the KeyMapper. 96 virtual int32_t num_keys() const = 0; 97 98 // Syncs all the changes made to the KeyMapper to disk. 99 // Returns any encountered IO errors. 100 // 101 // NOTE: To control disk-churn, Put() doesn't automatically persist every 102 // change to disk. The caller should explicitly call PersistToDisk() to make 103 // sure that the data is durable. 104 // 105 // Returns: 106 // OK on success 107 // INTERNAL on I/O error 108 virtual libtextclassifier3::Status PersistToDisk() = 0; 109 110 // Calculates and returns the disk usage in bytes. Rounds up to the nearest 111 // block size. 112 // 113 // Returns: 114 // Disk usage on success 115 // INTERNAL_ERROR on IO error 116 virtual libtextclassifier3::StatusOr<int64_t> GetDiskUsage() const = 0; 117 118 // Returns the size of the elements held in the key mapper. This excludes the 119 // size of any internal metadata of the key mapper, e.g. the key mapper's 120 // header. 121 // 122 // Returns: 123 // File size on success 124 // INTERNAL_ERROR on IO error 125 virtual libtextclassifier3::StatusOr<int64_t> GetElementsSize() const = 0; 126 127 // Computes the checksum of the key mapper and updates the header. 128 virtual libtextclassifier3::StatusOr<Crc32> UpdateChecksum() = 0; 129 130 // Returns the checksum of the key mapper. Does NOT update the header. 131 virtual libtextclassifier3::StatusOr<Crc32> GetChecksum() const = 0; 132 133 private: 134 static_assert(std::is_trivially_copyable<T>::value, 135 "T must be trivially copyable"); 136 }; 137 138 } // namespace lib 139 } // namespace icing 140 141 #endif // ICING_STORE_KEY_MAPPER_H_ 142