1 /* 2 ** Copyright 2011, The Android Open Source Project 3 ** 4 ** Licensed under the Apache License, Version 2.0 (the "License"); 5 ** you may not use this file except in compliance with the License. 6 ** You may obtain a copy of the License at 7 ** 8 ** http://www.apache.org/licenses/LICENSE-2.0 9 ** 10 ** Unless required by applicable law or agreed to in writing, software 11 ** distributed under the License is distributed on an "AS IS" BASIS, 12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 ** See the License for the specific language governing permissions and 14 ** limitations under the License. 15 */ 16 17 #ifndef ANDROID_BLOB_CACHE_H 18 #define ANDROID_BLOB_CACHE_H 19 20 #include <stddef.h> 21 22 #include <utils/RefBase.h> 23 #include <utils/SortedVector.h> 24 #include <utils/threads.h> 25 26 namespace android { 27 28 // A BlobCache is an in-memory cache for binary key/value pairs. All the public 29 // methods are thread-safe. 30 // 31 // The cache contents can be serialized to a file and reloaded in a subsequent 32 // execution of the program. This serialization is non-portable and should only 33 // be loaded by the device that generated it. 34 class BlobCache : public RefBase { 35 public: 36 37 // Create an empty blob cache. The blob cache will cache key/value pairs 38 // with key and value sizes less than or equal to maxKeySize and 39 // maxValueSize, respectively. The total combined size of ALL cache entries 40 // (key sizes plus value sizes) will not exceed maxTotalSize. 41 BlobCache(size_t maxKeySize, size_t maxValueSize, size_t maxTotalSize); 42 43 // set inserts a new binary value into the cache and associates it with the 44 // given binary key. If the key or value are too large for the cache then 45 // the cache remains unchanged. This includes the case where a different 46 // value was previously associated with the given key - the old value will 47 // remain in the cache. If the given key and value are small enough to be 48 // put in the cache (based on the maxKeySize, maxValueSize, and maxTotalSize 49 // values specified to the BlobCache constructor), then the key/value pair 50 // will be in the cache after set returns. Note, however, that a subsequent 51 // call to set may evict old key/value pairs from the cache. 52 // 53 // Preconditions: 54 // key != NULL 55 // 0 < keySize 56 // value != NULL 57 // 0 < valueSize 58 void set(const void* key, size_t keySize, const void* value, 59 size_t valueSize); 60 61 // The get function retrieves from the cache the binary value associated 62 // with a given binary key. If the key is present in the cache then the 63 // length of the binary value associated with that key is returned. If the 64 // value argument is non-NULL and the size of the cached value is less than 65 // valueSize bytes then the cached value is copied into the buffer pointed 66 // to by the value argument. If the key is not present in the cache then 0 67 // is returned and the buffer pointed to by the value argument is not 68 // modified. 69 // 70 // Note that when calling get multiple times with the same key, the later 71 // calls may fail, returning 0, even if earlier calls succeeded. The return 72 // value must be checked for each call. 73 // 74 // Preconditions: 75 // key != NULL 76 // 0 < keySize 77 // 0 <= valueSize 78 size_t get(const void* key, size_t keySize, void* value, size_t valueSize); 79 80 private: 81 // Copying is disallowed. 82 BlobCache(const BlobCache&); 83 void operator=(const BlobCache&); 84 85 // A random function helper to get around MinGW not having nrand48() 86 long int blob_random(); 87 88 // clean evicts a randomly chosen set of entries from the cache such that 89 // the total size of all remaining entries is less than mMaxTotalSize/2. 90 void clean(); 91 92 // isCleanable returns true if the cache is full enough for the clean method 93 // to have some effect, and false otherwise. 94 bool isCleanable() const; 95 96 // A Blob is an immutable sized unstructured data blob. 97 class Blob : public RefBase { 98 public: 99 Blob(const void* data, size_t size, bool copyData); 100 ~Blob(); 101 102 bool operator<(const Blob& rhs) const; 103 104 const void* getData() const; 105 size_t getSize() const; 106 107 private: 108 // Copying is not allowed. 109 Blob(const Blob&); 110 void operator=(const Blob&); 111 112 // mData points to the buffer containing the blob data. 113 const void* mData; 114 115 // mSize is the size of the blob data in bytes. 116 size_t mSize; 117 118 // mOwnsData indicates whether or not this Blob object should free the 119 // memory pointed to by mData when the Blob gets destructed. 120 bool mOwnsData; 121 }; 122 123 // A CacheEntry is a single key/value pair in the cache. 124 class CacheEntry { 125 public: 126 CacheEntry(); 127 CacheEntry(const sp<Blob>& key, const sp<Blob>& value); 128 CacheEntry(const CacheEntry& ce); 129 130 bool operator<(const CacheEntry& rhs) const; 131 const CacheEntry& operator=(const CacheEntry&); 132 133 sp<Blob> getKey() const; 134 sp<Blob> getValue() const; 135 136 void setValue(const sp<Blob>& value); 137 138 private: 139 140 // mKey is the key that identifies the cache entry. 141 sp<Blob> mKey; 142 143 // mValue is the cached data associated with the key. 144 sp<Blob> mValue; 145 }; 146 147 // mMaxKeySize is the maximum key size that will be cached. Calls to 148 // BlobCache::set with a keySize parameter larger than mMaxKeySize will 149 // simply not add the key/value pair to the cache. 150 const size_t mMaxKeySize; 151 152 // mMaxValueSize is the maximum value size that will be cached. Calls to 153 // BlobCache::set with a valueSize parameter larger than mMaxValueSize will 154 // simply not add the key/value pair to the cache. 155 const size_t mMaxValueSize; 156 157 // mMaxTotalSize is the maximum size that all cache entries can occupy. This 158 // includes space for both keys and values. When a call to BlobCache::set 159 // would otherwise cause this limit to be exceeded, either the key/value 160 // pair passed to BlobCache::set will not be cached or other cache entries 161 // will be evicted from the cache to make room for the new entry. 162 const size_t mMaxTotalSize; 163 164 // mTotalSize is the total combined size of all keys and values currently in 165 // the cache. 166 size_t mTotalSize; 167 168 // mRandState is the pseudo-random number generator state. It is passed to 169 // nrand48 to generate random numbers when needed. It must be protected by 170 // mMutex. 171 unsigned short mRandState[3]; 172 173 // mCacheEntries stores all the cache entries that are resident in memory. 174 // Cache entries are added to it by the 'set' method. 175 SortedVector<CacheEntry> mCacheEntries; 176 177 // mMutex is used to synchronize access to all member variables. It must be 178 // locked any time the member variables are written or read. 179 Mutex mMutex; 180 }; 181 182 } 183 184 #endif // ANDROID_BLOB_CACHE_H 185