Skip to content

Instantly share code, notes, and snippets.

@fish2000
Created February 20, 2017 01:29
Show Gist options
  • Save fish2000/b3a7d8accae8d046703f728b4ac82009 to your computer and use it in GitHub Desktop.
Save fish2000/b3a7d8accae8d046703f728b4ac82009 to your computer and use it in GitHub Desktop.
Basic Objective-C RocksDB Wrapper (w/ KVC)
//
// AXDatabase.h
// YoDogg
//
// Created by Alexander Böhn on 2/19/17.
// Copyright © 2017 Alexander Böhn. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface AXDatabase : NSObject {}
- (instancetype) initWithDatabase:(NSString*)dbFileName;
@end
@interface AXDatabase (NSKeyValueCoding)
- (void) setValue:(id)value forKey:(NSString*)key;
- (void) removeValueForKey:(NSString*)key;
- (id) valueForKey:(NSString*)key;
- (void) setObject:(id)object forKey:(NSString*)key;
- (void) removeObjectForKey:(NSString*)key;
- (id) objectForKey:(NSString*)key;
- (NSArray*) allObjects;
- (NSUInteger) count;
- (id) objectForKeyedSubscript:(NSString*)key;
- (void) setObject:(id)object forKeyedSubscript:(NSString*)key;
@end
//
// AXDatabase.mm
// YoDogg
//
// Created by Alexander Böhn on 2/19/17.
// Copyright © 2017 Alexander Böhn. All rights reserved.
//
#import "AXDatabase.h"
#include <string>
#include "rocksdb/db.h"
@interface AXDatabase ()
@property (nonatomic, unsafe_unretained) rocksdb::DB* rocks;
@end
@implementation AXDatabase
- (instancetype) initWithDatabase:(NSString*)dbFileName {
self = [super init];
rocksdb::Options options;
options.create_if_missing = true;
rocksdb::Status status = rocksdb::DB::Open(options, [dbFileName UTF8String], &_rocks);
NSLog(@"[AXDatabase initWithDatabase:%s] (status: %s)",
[dbFileName UTF8String],
status.ok() ? "OK" : "Not OK");
return self;
}
- (void) dealloc {
delete _rocks;
}
#pragma mark - Public API: NSKeyValueCoding
- (void) setValue:(id)value forKey:(NSString*)key {
NSData* data = [NSKeyedArchiver archivedDataWithRootObject:value];
if (data == nil) { return; }
std::string sval((char const*)data.bytes, data.length);
rocksdb::Status status = self.rocks->Put(rocksdb::WriteOptions(), [key UTF8String], sval);
rocksdb::Status flushed = self.rocks->Flush(rocksdb::FlushOptions());
}
- (void) removeValueForKey:(NSString*)key {
rocksdb::Status status = self.rocks->Delete(rocksdb::WriteOptions(), [key UTF8String]);
}
- (id) valueForKey:(NSString*)key {
std::string sval;
rocksdb::Status status = self.rocks->Get(rocksdb::ReadOptions(), [key UTF8String], &sval);
if (!status.ok()) { return nil; }
NSData* data = [[NSData alloc] initWithBytes:sval.data() length:sval.size()];
if (data == nil) { return nil; }
return [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
- (void) setObject:(id)object forKey:(NSString*)key {
NSData* data = [NSKeyedArchiver archivedDataWithRootObject:object];
if (data == nil) { return; }
std::string sval((char const*)data.bytes, data.length);
rocksdb::Status status = self.rocks->Put(rocksdb::WriteOptions(), [key UTF8String], sval);
rocksdb::Status flushed = self.rocks->Flush(rocksdb::FlushOptions());
}
- (void) removeObjectForKey:(NSString*)key {
rocksdb::Status status = self.rocks->Delete(rocksdb::WriteOptions(), [key UTF8String]);
}
- (id) objectForKey:(NSString*)key {
std::string sval;
rocksdb::Status status = self.rocks->Get(rocksdb::ReadOptions(), [key UTF8String], &sval);
if (!status.ok()) { return nil; }
NSData* data = [[NSData alloc] initWithBytes:sval.data() length:sval.size()];
if (data == nil) { return nil; }
return [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
- (NSArray*) allObjects {
rocksdb::Iterator* it = self.rocks->NewIterator(rocksdb::ReadOptions());
NSMutableArray* out = [[NSMutableArray alloc] init];
for (it->SeekToFirst(); it->Valid(); it->Next()) {
std::string sval(it->value().ToString());
NSData* data = [[NSData alloc] initWithBytes:sval.data() length:sval.size()];
if (data != nil) {
[out addObject:[NSKeyedUnarchiver unarchiveObjectWithData:data]];
}
}
delete it;
return [NSArray arrayWithArray:out];
}
- (NSUInteger) count {
uint64_t cnt;
bool status = self.rocks->GetIntProperty(rocksdb::DB::Properties::kEstimateNumKeys, &cnt);
if (status) {
return cnt;
}
return 0;
}
- (id) objectForKeyedSubscript:(NSString*)key {
std::string sval;
rocksdb::Status status = self.rocks->Get(rocksdb::ReadOptions(), [key UTF8String], &sval);
if (!status.ok()) { return nil; }
NSData* data = [[NSData alloc] initWithBytes:sval.data() length:sval.size()];
if (data == nil) { return nil; }
return [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
- (void) setObject:(id)object forKeyedSubscript:(NSString*)key {
NSData* data = [NSKeyedArchiver archivedDataWithRootObject:object];
if (data == nil) { return; }
std::string sval((char const*)data.bytes, data.length);
rocksdb::Status status = self.rocks->Put(rocksdb::WriteOptions(), [key UTF8String], sval);
rocksdb::Status flushed = self.rocks->Flush(rocksdb::FlushOptions());
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment