Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve RocksDB interface #23

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 106 additions & 4 deletions Code/RocksDB.h
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ NS_ASSUME_NONNULL_BEGIN
/**
Returns the object for the given key.

@peram aKey The key for object.
@param aKey The key for object.
@param error If an error occurs, upon return contains an `NSError` object that describes the problem.
@return The object for the given key.
*/
Expand All @@ -358,7 +358,7 @@ NS_ASSUME_NONNULL_BEGIN
/**
Returns the object for the given key.

@peram aKey The key for object.
@param aKey The key for object.
@param error If an error occurs, upon return contains an `NSError` object that describes the problem.
@param readOptions A block with a `RocksDBReadOptions` instance for configuring this read operation.
@return The object for the given key.
Expand All @@ -369,6 +369,35 @@ NS_ASSUME_NONNULL_BEGIN
readOptions:(nullable void (^)(RocksDBReadOptions *readOptions))readOptions
error:(NSError * _Nullable *)error;

/**
If the key definitely does not exist in the database, then this method
returns false, else true.

This check is potentially lighter-weight than invoking dataForKey. One way
to make this lighter weight is to avoid doing any IOs.

@param aKey The key for object to check.
@param value out parameter if a value is found in block-cache.
@return The object for the given key.
*/
- (BOOL)keyMayExist:(NSData *)aKey value:(NSString * _Nullable *_Nullable)value;

/**
If the key definitely does not exist in the database, then this method
returns false, else true.

This check is potentially lighter-weight than invoking dataForKey. One way
to make this lighter weight is to avoid doing any IOs.

@param aKey The key for object to check.
@param readOptions `RocksDBReadOptions` instance for configuring this read operation.
@param value out parameter if a value is found in block-cache.
@return The object for the given key.
*/
- (BOOL)keyMayExist:(NSData *)aKey
readOptions:(nullable void (^)(RocksDBReadOptions *readOptions))readOptions
value:(NSString * _Nullable *_Nullable)value;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really sure about the pass-by-ref parameter here. This breaks the trailing closure syntax and wouldn't translate nicely when used in Swift. Instead of returning BOOL how about returning a nullable NSString *.


@end

#pragma mark - Delete operations
Expand All @@ -382,7 +411,7 @@ NS_ASSUME_NONNULL_BEGIN
/**
Deletes the object for the given key.

@peram aKey The key to delete.
@param aKey The key to delete.
@param error If an error occurs, upon return contains an `NSError` object that describes the problem.
@return `YES` if the operation succeeded, `NO` otherwise
*/
Expand All @@ -391,7 +420,7 @@ NS_ASSUME_NONNULL_BEGIN
/**
Deletes the object for the given key.

@peram aKey The key to delete.
@param aKey The key to delete.
@param error If an error occurs, upon return contains an `NSError` object that describes the problem.
@param writeOptions A block with a `RocksDBWriteOptions` instance for configuring this delete operation.
@return `YES` if the operation succeeded, `NO` otherwise
Expand Down Expand Up @@ -571,4 +600,77 @@ NS_ASSUME_NONNULL_BEGIN

@end

#pragma mark - File Deletions

@interface RocksDB (FileDeletion)

///--------------------------------
/// @name File Deletions
///--------------------------------

/**
Prevent file deletions. Compactions will continue to occur,
but no obsolete files will be deleted. Calling this multiple
times have the same effect as calling it once.
@param error RocksDBError If an error occurs
*/
- (void)disableFileDeletions:(NSError * __autoreleasing *)error;

/**
Allow compactions to delete obsolete files.
If force == true, the call to EnableFileDeletions()
will guarantee that file deletions are enabled after
the call, even if DisableFileDeletions() was called
multiple times before.

If force == false, EnableFileDeletions will only
enable file deletion after it's been called at least
as many times as DisableFileDeletions(), enabling
the two methods to be called by two threads
concurrently without synchronization
-- i.e., file deletions will be enabled only after both
threads call EnableFileDeletions()

@param force boolean value described above.
@param error RocksDBError If an error occurs
*/
- (void)enableFileDelections:(BOOL)force error:(NSError * __autoreleasing *)error;

/**
Delete the file name from the db directory and update the internal state to
reflect that. Supports deletion of sst and log files only. 'name' must be
path relative to the db directory. eg. 000001.sst, /archive/000003.log

@param name the file name
@param error RocksDBError If an error occurs
*/
- (void)deleteFile:(NSString *)name error:(NSError * __autoreleasing *)error;

@end

#pragma mark - Background Work

@interface RocksDB (BackgroundWork)

///--------------------------------
/// @name Background Work
///--------------------------------

/**
This function will wait until all currently running background processes
finish. After it returns, no background process will be run until
.continueBackgroundWork] is called

@param error RocksDBError If an error occurs when pausing background work
*/
- (void)pauseBackgroundWork:(NSError * __autoreleasing *)error;

/**
Resumes background work which was suspended by previously calling .pauseBackground
@param error RocksDBError If an error occurs when resuming background work
*/
- (void)continueBackgroundWork:(NSError * __autoreleasing *)error;

@end

NS_ASSUME_NONNULL_END
87 changes: 86 additions & 1 deletion Code/RocksDB.mm
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ - (void)setDefaultReadOptions:(void (^)(RocksDBReadOptions *))readOptionsBlock w

#if !(defined(ROCKSDB_LITE) && defined(TARGET_OS_IPHONE))

#pragma mark - Peroperties
#pragma mark - Properties

- (NSString *)valueForProperty:(RocksDBProperty)property
{
Expand Down Expand Up @@ -455,6 +455,32 @@ - (NSData *)dataForKey:(NSData *)aKey
return DataFromSlice(rocksdb::Slice(value));
}

- (BOOL)keyMayExist:(NSData *)aKey value:(NSString * _Nullable *)value
{
return [self keyMayExist:aKey readOptions:nil value:value];
}

- (BOOL)keyMayExist:(NSData *)aKey
readOptions:(nullable void (^)(RocksDBReadOptions *readOptions))readOptionsBlock
value:(NSString * _Nullable *)value
{
RocksDBReadOptions *readOptions = [_readOptions copy];
if (readOptionsBlock) {
readOptionsBlock(readOptions);
}

bool found = NO;
std::string stringValue;
_db->KeyMayExist(readOptions.options,
_columnFamily,
SliceFromData(aKey),
&stringValue,
&found);

*value = [NSString stringWithUTF8String:stringValue.c_str()];
return found;
}

#pragma mark - Delete Operations

- (BOOL)deleteDataForKey:(NSData *)aKey error:(NSError * __autoreleasing *)error
Expand Down Expand Up @@ -637,4 +663,63 @@ - (BOOL)compactRange:(RocksDBKeyRange *)range
return YES;
}

#pragma mark - File Deletions

- (void)disableFileDeletions:(NSError * __autoreleasing *)error
{
rocksdb::Status status = _db->DisableFileDeletions();
if (!status.ok()) {
NSError *temp = [RocksDBError errorWithRocksStatus:status];
if (error && *error == nil) {
*error = temp;
}
}
}

- (void)enableFileDelections:(BOOL)force error:(NSError * __autoreleasing *)error
{
rocksdb::Status status = _db->EnableFileDeletions(force);
if (!status.ok()) {
NSError *temp = [RocksDBError errorWithRocksStatus:status];
if (error && *error == nil) {
*error = temp;
}
}
}

- (void)deleteFile:(NSString *)name error:(NSError * __autoreleasing *)error
{
rocksdb::Status status = _db->DeleteFile(name.UTF8String);
if (!status.ok()) {
NSError *temp = [RocksDBError errorWithRocksStatus:status];
if (error && *error == nil) {
*error = temp;
}
}
}

#pragma mark - Background Work

- (void)pauseBackgroundWork:(NSError * __autoreleasing *)error
{
rocksdb::Status status = _db->PauseBackgroundWork();
if (!status.ok()) {
NSError *temp = [RocksDBError errorWithRocksStatus:status];
if (error && *error == nil) {
*error = temp;
}
}
}

- (void)continueBackgroundWork:(NSError * __autoreleasing *)error
{
rocksdb::Status status = _db->ContinueBackgroundWork();
if (!status.ok()) {
NSError *temp = [RocksDBError errorWithRocksStatus:status];
if (error && *error == nil) {
*error = temp;
}
}
}

@end