123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 |
- //
- // YYKVStorage.h
- // YYKit <https://github.com/ibireme/YYKit>
- //
- // Created by ibireme on 15/4/22.
- // Copyright (c) 2015 ibireme.
- //
- // This source code is licensed under the MIT-style license found in the
- // LICENSE file in the root directory of this source tree.
- //
- #import <Foundation/Foundation.h>
- NS_ASSUME_NONNULL_BEGIN
- /**
- YYKVStorageItem is used by `YYKVStorage` to store key-value pair and meta data.
- Typically, you should not use this class directly.
- */
- @interface YYKVStorageItem : NSObject
- @property (nonatomic, strong) NSString *key; ///< key
- @property (nonatomic, strong) NSData *value; ///< value
- @property (nullable, nonatomic, strong) NSString *filename; ///< filename (nil if inline)
- @property (nonatomic) int size; ///< value's size in bytes
- @property (nonatomic) int modTime; ///< modification unix timestamp
- @property (nonatomic) int accessTime; ///< last access unix timestamp
- @property (nullable, nonatomic, strong) NSData *extendedData; ///< extended data (nil if no extended data)
- @end
- /**
- Storage type, indicated where the `YYKVStorageItem.value` stored.
-
- @discussion Typically, write data to sqlite is faster than extern file, but
- reading performance is dependent on data size. In my test (on iPhone 6 64G),
- read data from extern file is faster than from sqlite when the data is larger
- than 20KB.
-
- * If you want to store large number of small datas (such as contacts cache),
- use YYKVStorageTypeSQLite to get better performance.
- * If you want to store large files (such as image cache),
- use YYKVStorageTypeFile to get better performance.
- * You can use YYKVStorageTypeMixed and choice your storage type for each item.
-
- See <http://www.sqlite.org/intern-v-extern-blob.html> for more information.
- */
- typedef NS_ENUM(NSUInteger, YYKVStorageType) {
-
- /// The `value` is stored as a file in file system.
- YYKVStorageTypeFile = 0,
-
- /// The `value` is stored in sqlite with blob type.
- YYKVStorageTypeSQLite = 1,
-
- /// The `value` is stored in file system or sqlite based on your choice.
- YYKVStorageTypeMixed = 2,
- };
- /**
- YYKVStorage is a key-value storage based on sqlite and file system.
- Typically, you should not use this class directly.
-
- @discussion The designated initializer for YYKVStorage is `initWithPath:type:`.
- After initialized, a directory is created based on the `path` to hold key-value data.
- Once initialized you should not read or write this directory without the instance.
-
- You may compile the latest version of sqlite and ignore the libsqlite3.dylib in
- iOS system to get 2x~4x speed up.
-
- @warning The instance of this class is *NOT* thread safe, you need to make sure
- that there's only one thread to access the instance at the same time. If you really
- need to process large amounts of data in multi-thread, you should split the data
- to multiple KVStorage instance (sharding).
- */
- @interface YYKVStorage : NSObject
- #pragma mark - Attribute
- ///=============================================================================
- /// @name Attribute
- ///=============================================================================
- @property (nonatomic, readonly) NSString *path; ///< The path of this storage.
- @property (nonatomic, readonly) YYKVStorageType type; ///< The type of this storage.
- @property (nonatomic) BOOL errorLogsEnabled; ///< Set `YES` to enable error logs for debug.
- #pragma mark - Initializer
- ///=============================================================================
- /// @name Initializer
- ///=============================================================================
- - (instancetype)init UNAVAILABLE_ATTRIBUTE;
- + (instancetype)new UNAVAILABLE_ATTRIBUTE;
- /**
- The designated initializer.
-
- @param path Full path of a directory in which the storage will write data. If
- the directory is not exists, it will try to create one, otherwise it will
- read the data in this directory.
- @param type The storage type. After first initialized you should not change the
- type of the specified path.
- @return A new storage object, or nil if an error occurs.
- @warning Multiple instances with the same path will make the storage unstable.
- */
- - (nullable instancetype)initWithPath:(NSString *)path type:(YYKVStorageType)type NS_DESIGNATED_INITIALIZER;
- #pragma mark - Save Items
- ///=============================================================================
- /// @name Save Items
- ///=============================================================================
- /**
- Save an item or update the item with 'key' if it already exists.
-
- @discussion This method will save the item.key, item.value, item.filename and
- item.extendedData to disk or sqlite, other properties will be ignored. item.key
- and item.value should not be empty (nil or zero length).
-
- If the `type` is YYKVStorageTypeFile, then the item.filename should not be empty.
- If the `type` is YYKVStorageTypeSQLite, then the item.filename will be ignored.
- It the `type` is YYKVStorageTypeMixed, then the item.value will be saved to file
- system if the item.filename is not empty, otherwise it will be saved to sqlite.
-
- @param item An item.
- @return Whether succeed.
- */
- - (BOOL)saveItem:(YYKVStorageItem *)item;
- /**
- Save an item or update the item with 'key' if it already exists.
-
- @discussion This method will save the key-value pair to sqlite. If the `type` is
- YYKVStorageTypeFile, then this method will failed.
-
- @param key The key, should not be empty (nil or zero length).
- @param value The key, should not be empty (nil or zero length).
- @return Whether succeed.
- */
- - (BOOL)saveItemWithKey:(NSString *)key value:(NSData *)value;
- /**
- Save an item or update the item with 'key' if it already exists.
-
- @discussion
- If the `type` is YYKVStorageTypeFile, then the `filename` should not be empty.
- If the `type` is YYKVStorageTypeSQLite, then the `filename` will be ignored.
- It the `type` is YYKVStorageTypeMixed, then the `value` will be saved to file
- system if the `filename` is not empty, otherwise it will be saved to sqlite.
-
- @param key The key, should not be empty (nil or zero length).
- @param value The key, should not be empty (nil or zero length).
- @param filename The filename.
- @param extendedData The extended data for this item (pass nil to ignore it).
-
- @return Whether succeed.
- */
- - (BOOL)saveItemWithKey:(NSString *)key
- value:(NSData *)value
- filename:(nullable NSString *)filename
- extendedData:(nullable NSData *)extendedData;
- #pragma mark - Remove Items
- ///=============================================================================
- /// @name Remove Items
- ///=============================================================================
- /**
- Remove an item with 'key'.
-
- @param key The item's key.
- @return Whether succeed.
- */
- - (BOOL)removeItemForKey:(NSString *)key;
- /**
- Remove items with an array of keys.
-
- @param keys An array of specified keys.
-
- @return Whether succeed.
- */
- - (BOOL)removeItemForKeys:(NSArray<NSString *> *)keys;
- /**
- Remove all items which `value` is larger than a specified size.
-
- @param size The maximum size in bytes.
- @return Whether succeed.
- */
- - (BOOL)removeItemsLargerThanSize:(int)size;
- /**
- Remove all items which last access time is earlier than a specified timestamp.
-
- @param time The specified unix timestamp.
- @return Whether succeed.
- */
- - (BOOL)removeItemsEarlierThanTime:(int)time;
- /**
- Remove items to make the total size not larger than a specified size.
- The least recently used (LRU) items will be removed first.
-
- @param maxSize The specified size in bytes.
- @return Whether succeed.
- */
- - (BOOL)removeItemsToFitSize:(int)maxSize;
- /**
- Remove items to make the total count not larger than a specified count.
- The least recently used (LRU) items will be removed first.
-
- @param maxCount The specified item count.
- @return Whether succeed.
- */
- - (BOOL)removeItemsToFitCount:(int)maxCount;
- /**
- Remove all items in background queue.
-
- @discussion This method will remove the files and sqlite database to a trash
- folder, and then clear the folder in background queue. So this method is much
- faster than `removeAllItemsWithProgressBlock:endBlock:`.
-
- @return Whether succeed.
- */
- - (BOOL)removeAllItems;
- /**
- Remove all items.
-
- @warning You should not send message to this instance in these blocks.
- @param progress This block will be invoked during removing, pass nil to ignore.
- @param end This block will be invoked at the end, pass nil to ignore.
- */
- - (void)removeAllItemsWithProgressBlock:(nullable void(^)(int removedCount, int totalCount))progress
- endBlock:(nullable void(^)(BOOL error))end;
- #pragma mark - Get Items
- ///=============================================================================
- /// @name Get Items
- ///=============================================================================
- /**
- Get item with a specified key.
-
- @param key A specified key.
- @return Item for the key, or nil if not exists / error occurs.
- */
- - (nullable YYKVStorageItem *)getItemForKey:(NSString *)key;
- /**
- Get item information with a specified key.
- The `value` in this item will be ignored.
-
- @param key A specified key.
- @return Item information for the key, or nil if not exists / error occurs.
- */
- - (nullable YYKVStorageItem *)getItemInfoForKey:(NSString *)key;
- /**
- Get item value with a specified key.
-
- @param key A specified key.
- @return Item's value, or nil if not exists / error occurs.
- */
- - (nullable NSData *)getItemValueForKey:(NSString *)key;
- /**
- Get items with an array of keys.
-
- @param keys An array of specified keys.
- @return An array of `YYKVStorageItem`, or nil if not exists / error occurs.
- */
- - (nullable NSArray<YYKVStorageItem *> *)getItemForKeys:(NSArray<NSString *> *)keys;
- /**
- Get item infomartions with an array of keys.
- The `value` in items will be ignored.
-
- @param keys An array of specified keys.
- @return An array of `YYKVStorageItem`, or nil if not exists / error occurs.
- */
- - (nullable NSArray<YYKVStorageItem *> *)getItemInfoForKeys:(NSArray<NSString *> *)keys;
- /**
- Get items value with an array of keys.
-
- @param keys An array of specified keys.
- @return A dictionary which key is 'key' and value is 'value', or nil if not
- exists / error occurs.
- */
- - (nullable NSDictionary<NSString *, NSData *> *)getItemValueForKeys:(NSArray<NSString *> *)keys;
- #pragma mark - Get Storage Status
- ///=============================================================================
- /// @name Get Storage Status
- ///=============================================================================
- /**
- Whether an item exists for a specified key.
-
- @param key A specified key.
-
- @return `YES` if there's an item exists for the key, `NO` if not exists or an error occurs.
- */
- - (BOOL)itemExistsForKey:(NSString *)key;
- /**
- Get total item count.
- @return Total item count, -1 when an error occurs.
- */
- - (int)getItemsCount;
- /**
- Get item value's total size in bytes.
- @return Total size in bytes, -1 when an error occurs.
- */
- - (int)getItemsSize;
- @end
- NS_ASSUME_NONNULL_END
|