Skip to content
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
4 changes: 4 additions & 0 deletions Core/PARStore.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,14 @@ extern NSString *PARStoreDidSyncNotification;
@property (readonly) BOOL deleted;
@property (readonly) BOOL inMemory;
@property (readonly) BOOL inMemoryCacheEnabled;
@property (readonly) BOOL fileCoordinationEnabled;

/// @name Memory Cache
- (void)disableInMemoryCache;

/// @name File Coordination and Presentation
- (void)disableFileCoordination;

/// @name Adding and Accessing Values
- (nullable id)propertyListValueForKey:(NSString *)key;
- (void)setPropertyListValue:(nullable id)plist forKey:(NSString *)key;
Expand Down
60 changes: 51 additions & 9 deletions Core/PARStore.m
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,24 @@
NSString *const ParentTimestampAttributeName = @"parentTimestamp";


// A subclass of NSFileCoordinator that doesn't use coordination.
// This is used to disable coordination, for a performance boost when it is not needed.
@interface _PARFileUncoordinator : NSFileCoordinator
@end

@implementation _PARFileUncoordinator

- (void)coordinateReadingItemAtURL:(NSURL *)url options:(NSFileCoordinatorReadingOptions)options error:(NSError * __autoreleasing *)outError byAccessor:(void NS_NOESCAPE (^)(NSURL *))reader {
reader(url);
}

- (void)coordinateWritingItemAtURL:(NSURL *)url options:(NSFileCoordinatorWritingOptions)options error:(NSError * __autoreleasing *)outError byAccessor:(void NS_NOESCAPE (^)(NSURL *))writer {
writer(url);
}

@end


@interface PARStore ()
@property (readwrite, copy) NSURL *storeURL;
@property (readwrite, copy) NSString *deviceIdentifier;
Expand Down Expand Up @@ -64,6 +82,9 @@ @interface PARStore ()
// queue needed for NSFilePresenter protocol
@property (retain) NSOperationQueue *presenterQueue;

// File coordination
@property (readwrite, nonatomic) BOOL _fileCoordinationEnabled;

// responding to file system events (Mac only)
#if TARGET_OS_IPHONE | TARGET_IPHONE_SIMULATOR
#elif TARGET_OS_MAC
Expand Down Expand Up @@ -115,6 +136,7 @@ - (instancetype)initWithURL:(NSURL *)url deviceIdentifier:(NSString *)identifier
self._loaded = NO;
self._deleted = NO;
self._inMemoryCacheEnabled = YES;
self._fileCoordinationEnabled = YES;

// in memory store?
if (url == nil)
Expand Down Expand Up @@ -149,6 +171,18 @@ - (void)disableInMemoryCache {
self._memory = nil;
}

#pragma mark - File Coordination and Presentation

- (BOOL)fileCoordinationEnabled {
return self._fileCoordinationEnabled;
}

- (void)disableFileCoordination {
[NSFileCoordinator removeFilePresenter:self];
self._fileCoordinationEnabled = NO;
self.presenterQueue = nil;
}

#pragma mark - Loading / Closing Memory Layer

// loading = populating the memory cache with the values from disk
Expand All @@ -172,7 +206,7 @@ - (void)_load

[self _sync];

if ([self loaded])
if ([self loaded] && self._fileCoordinationEnabled)
{
// DebugLog(@"%@ added as file presenter", self.deviceIdentifier);
[NSFileCoordinator addFilePresenter:self];
Expand Down Expand Up @@ -310,6 +344,14 @@ - (NSString *)readwriteDirectoryPath
return [self directoryPathForDeviceIdentifier:self.deviceIdentifier];
}

- (NSFileCoordinator *)newFileCoordinator {
if (self._fileCoordinationEnabled) {
return [[NSFileCoordinator alloc] initWithFilePresenter:self];
} else {
return [[_PARFileUncoordinator alloc] init];
}
}

- (BOOL)prepareFilePackageWithError:(NSError **)error
{
if (self._inMemory)
Expand Down Expand Up @@ -358,7 +400,7 @@ - (BOOL)prepareFilePackageWithError:(NSError **)error
// create file package if necessary
if (success && !fileExists)
{
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:self];
NSFileCoordinator *coordinator = [self newFileCoordinator];
[coordinator coordinateWritingItemAtURL:self.storeURL options:NSFileCoordinatorWritingForReplacing error:NULL byAccessor:^(NSURL *newURL) {
NSError *fmError = nil;
success = [[NSFileManager defaultManager] createDirectoryAtURL:self.storeURL withIntermediateDirectories:NO attributes:nil error:&fmError] && [[NSFileManager defaultManager] createDirectoryAtPath:devicesPath withIntermediateDirectories:NO attributes:nil error:&fmError];
Expand All @@ -370,7 +412,7 @@ - (BOOL)prepareFilePackageWithError:(NSError **)error
// create deviceID subfolder if necessary
if (success && !identifierDirExists)
{
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:self];
NSFileCoordinator *coordinator = [self newFileCoordinator];
[coordinator coordinateWritingItemAtURL:[NSURL fileURLWithPath:identifierPath] options:NSFileCoordinatorWritingForReplacing error:NULL byAccessor:^(NSURL *newURL) {

NSError *fmError = nil;
Expand Down Expand Up @@ -656,7 +698,7 @@ - (BOOL)_save:(NSError **)error

// save
NSError *localError = nil;
NSFileCoordinator *coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:self];
NSFileCoordinator *coordinator = [self newFileCoordinator];
NSURL *databaseURL = [NSURL fileURLWithPath:[[self readwriteDirectoryPath] stringByAppendingPathComponent:PARDatabaseFileName]];
NSError *coordinatorError = nil;
__block NSError *saveError = nil;
Expand Down Expand Up @@ -1218,7 +1260,7 @@ - (BOOL)writeBlobData:(NSData *)data toPath:(NSString *)path error:(NSError **)e
__block NSError *localError = nil;
NSURL *fileURL = [[self blobDirectoryURL] URLByAppendingPathComponent:path];
NSError *coordinatorError = nil;
[[[NSFileCoordinator alloc] initWithFilePresenter:self] coordinateWritingItemAtURL:fileURL options:NSFileCoordinatorWritingForReplacing error:&coordinatorError byAccessor:^(NSURL *newURL)
[[self newFileCoordinator] coordinateWritingItemAtURL:fileURL options:NSFileCoordinatorWritingForReplacing error:&coordinatorError byAccessor:^(NSURL *newURL)
{
// create parent dirs (it will fail if one of the dir already exists but is a file)
NSError *errorCreatingDir = nil;
Expand Down Expand Up @@ -1294,7 +1336,7 @@ - (BOOL)writeBlobFromPath:(NSString *)sourcePath toPath:(NSString *)targetSubpat
__block NSError *localError = nil;
NSURL *targetURL = [[self blobDirectoryURL] URLByAppendingPathComponent:targetSubpath];
NSError *coordinatorError = nil;
[[[NSFileCoordinator alloc] initWithFilePresenter:self] coordinateWritingItemAtURL:targetURL options:NSFileCoordinatorWritingForReplacing error:&coordinatorError byAccessor:^(NSURL *newTargetURL)
[[self newFileCoordinator] coordinateWritingItemAtURL:targetURL options:NSFileCoordinatorWritingForReplacing error:&coordinatorError byAccessor:^(NSURL *newTargetURL)
{
// create parent dirs (it will fail if one of the dir already exists but is a file)
NSError *errorCreatingDir = nil;
Expand Down Expand Up @@ -1366,7 +1408,7 @@ - (BOOL)deleteBlobAtPath:(NSString *)path error:(NSError **)error
__block NSError *localError = nil;
NSURL *fileURL = [[self blobDirectoryURL] URLByAppendingPathComponent:path];
NSError *coordinatorError = nil;
[[[NSFileCoordinator alloc] initWithFilePresenter:self] coordinateWritingItemAtURL:fileURL options:NSFileCoordinatorWritingForReplacing error:&coordinatorError byAccessor:^(NSURL *newURL)
[[self newFileCoordinator] coordinateWritingItemAtURL:fileURL options:NSFileCoordinatorWritingForReplacing error:&coordinatorError byAccessor:^(NSURL *newURL)
{
// write to disk (overwrite any file that was at that same path before)
NSError *error = nil;
Expand Down Expand Up @@ -1416,7 +1458,7 @@ - (NSData *)blobDataAtPath:(NSString *)path error:(NSError **)error;
NSURL *fileURL = [[self blobDirectoryURL] URLByAppendingPathComponent:path];
NSError *coordinatorError = nil;
__block NSData *data = nil;
[[[NSFileCoordinator alloc] initWithFilePresenter:self] coordinateReadingItemAtURL:fileURL options:NSFileCoordinatorReadingWithoutChanges error:&coordinatorError byAccessor:^(NSURL *newURL)
[[self newFileCoordinator] coordinateReadingItemAtURL:fileURL options:NSFileCoordinatorReadingWithoutChanges error:&coordinatorError byAccessor:^(NSURL *newURL)
{
NSError *errorReadingData = nil;
data = [NSData dataWithContentsOfURL:newURL options:NSDataReadingMappedIfSafe error:&errorReadingData];
Expand Down Expand Up @@ -1468,7 +1510,7 @@ - (void)enumerateBlobs:(void(^)(NSString *path))block
else
{
__block NSArray *urls;
[[[NSFileCoordinator alloc] initWithFilePresenter:self] coordinateReadingItemAtURL:[self blobDirectoryURL] options:NSFileCoordinatorReadingWithoutChanges error:NULL byAccessor:^(NSURL *newURL)
[[self newFileCoordinator] coordinateReadingItemAtURL:[self blobDirectoryURL] options:NSFileCoordinatorReadingWithoutChanges error:NULL byAccessor:^(NSURL *newURL)
{
NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtURL:[self blobDirectoryURL] includingPropertiesForKeys:nil options:(NSDirectoryEnumerationSkipsPackageDescendants|NSDirectoryEnumerationSkipsHiddenFiles|NSDirectoryEnumerationSkipsSubdirectoryDescendants) errorHandler:nil];
NSFileManager *fileManager = [[NSFileManager alloc] init];
Expand Down