A feature-complete Objective-C wrapper for Google's LevelDB, a fast key-value store written by Google.
- Drag all
.h
and.mm
files into your project. - Clone Google's leveldb, preferably as a submodule of your project
- In the leveldb library source directory, run
make PLATFORM=IOS
to build the library file - Add libleveldb.a to your project as a dependency
- Add the leveldb/include path to your header path
Although Google's leveldb library is written in C++, this wrapper was written in a way that you can import Objective-LevelDB into your Objective-C
project without worrying about turning your .m
files into .mm
.
LevelDB *ldb = [LevelDB databaseInLibraryWithName:@"test.ldb"];
ldb.encoder = ^ NSData * (LeveldBKey *key, id object) {
// return some data, given an object
}
ldb.decoder = ^ id (LeveldBKey *key, NSData * data) {
// return an object, given some data
}
[ldb setObject:@"laval" forKey:@"string_test"];
NSLog(@"String Value: %@", [ldb objectForKey:@"string_test"]);
[ldb setObject:[NSDictionary dictionaryWithObjectsAndKeys:@"val1", @"key1", @"val2", @"key2", nil] forKey:@"dict_test"];
NSLog(@"Dictionary Value: %@", [ldb objectForKey:@"dict_test"]);
All available methods can be found in its header file
[self enumerateKeysAndObjectsUsingBlock:^(LevelDBKey *key, id value, BOOL *stop) {
// This step is necessary since the key could be a string or raw data (use NSDataFromLevelDBKey in that case)
NSString *keyString = NSStringFromLevelDBKey(key); // Assumes UTF-8 encoding
// Do something clever
}];
// Start enumeration at a certain key
[self enumerateKeysAndObjectsUsingBlock:^(LevelDBKey *key, id value, BOOL *stop) {
// Do something else clever
}
startingAtKey:key];
// Filter with a NSPredicate instance
[self enumerateKeysAndObjectsUsingBlock:^(LevelDBKey *key, id value, BOOL *stop) {
// Do something else clever, like really clever
}
startingAtKey:key
filteredWithPredicate:predicate];
// Iterate backward
More iteration methods are available, just have a look at the header section
Snapshot *snap = [ldb getSnapshot];
[ldb removeObjectForKey:@"string_test"];
// These calls will reflect the state of ldb when the snapshot was taken
NSLog(@"String Value: %@", [snap objectForKey:@"string_test"]);
NSLog(@"Dictionary Value: %@", [ldb objectForKey:@"dict_test"]);
// Dispose (automatically done in dealloc)
[snap release];
All available methods can be found in its header file
Writebatch *wb = [Writebatch writebatchFromDB:ldb];
[wb setObject:@{ @"foo" : @"bar" } forKey: @"another_test"];
[wb removeObjectForKey:@"dict_test"];
// Those changes aren't yet applied to ldb
// To apply them in batch,
[wb apply];
All available methods can be found in its header file
// The following values are the default
LevelDBOptions options = [LevelDB makeOptions];
options.createIfMissing = true;
options.errorIfExists = false;
options.paranoidCheck = false;
options.compression = true;
options.filterPolicy = 0; // Size in bits per key, allocated for a bloom filter, used in testing presence of key
options.cacheSize = 0; // Size in bytes, allocated for a LRU cache used for speeding up lookups
// Then, you can provide it when initializing a db instance.
LevelDB *ldb = [LevelDB databaseInLibraryWithName:@"test.ldb" andOptions:options];
db.safe = true; // Make sure to data was actually written to disk before returning from write operations.
[ldb setObject:@"laval" forKey:@"string_test"];
[ldb setObject:[NSDictionary dictionaryWithObjectsAndKeys:@"val1", @"key1", @"val2", @"key2", nil] forKey:@"dict_test"];
db.safe = false; // Switch back to default
db.useCache = false; // Do not use DB cache when reading data (default to true);
[ldb addObserver:self selector:@selector(valueChanged:) forKey:key];
id observer = [ldb addObserverForKey:key queue:queue usingBlock:^(NSNotification *note){
NSString *key = note.userInfo[kLevelDBKey];
id value = note.userInfo[kLevelDBValue];
id changeType = note.userInfo[kLevelDBChangeType]; // Can be kLevelDBChangeTypePut or kLevelDBChangeTypeDelete
}];
[ldb pauseObserving];
[ldb removeAllObjects];
[ldb resumeObserving];
// To avoid retain cycles, just like with NSNotificationCenter, you need to remove the observers when you don't need them anymore
[ldb removeObserver:observer];
[ldb removeObserver:self forKey:key];
Distributed under the MIT license