mirror of
https://github.com/firebase/firebase-ios-sdk
synced 2026-11-09 22:36:01 +05:45
Revert GDTCORStorage changes for now (#5778)
* Revert "Refactor event saving and searching (#5773)" This reverts commita61786cbf1. * Revert "Expand the storage protocol and provide an event iterator (#5742)" This reverts commit641d8531a3. * Revert "Implement helpers for storing and finding events (#5738)" This reverts commit9a0aed81b0.
This commit is contained in:
1 parent
4158014aae
commit
93eb6d8c48
10 files changed
+21
-557
No files matched your search
@@ -20,21 +20,12 @@
|
||||
#import <GoogleDataTransport/GDTCORConsoleLogger.h>
|
||||
#import <GoogleDataTransport/GDTCOREvent.h>
|
||||
#import <GoogleDataTransport/GDTCORLifecycle.h>
|
||||
#import <GoogleDataTransport/GDTCORPlatform.h>
|
||||
#import <GoogleDataTransport/GDTCORPrioritizer.h>
|
||||
#import <GoogleDataTransport/GDTCORStorageEventSelector.h>
|
||||
|
||||
#import "GDTCORLibrary/Private/GDTCOREvent_Private.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORFlatFileStorageIterator.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORRegistrar_Private.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORUploadCoordinator.h"
|
||||
|
||||
NSString *const gGDTCORFlatFileStorageEventDataPathKey = @"DataPath";
|
||||
|
||||
NSString *const gGDTCORFlatFileStorageMappingIDPathKey = @"MappingIDPath";
|
||||
|
||||
NSString *const gGDTCORFlatFileStorageQoSTierPathKey = @"QoSTierPath";
|
||||
|
||||
@implementation GDTCORFlatFileStorage
|
||||
|
||||
+ (void)load {
|
||||
@@ -60,28 +51,7 @@ NSString *const gGDTCORFlatFileStorageQoSTierPathKey = @"QoSTierPath";
|
||||
return archivePath;
|
||||
}
|
||||
|
||||
+ (NSString *)baseEventStoragePath {
|
||||
static NSString *eventDataPath;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
eventDataPath =
|
||||
[GDTCORRootDirectory() URLByAppendingPathComponent:NSStringFromClass([self class])
|
||||
isDirectory:YES]
|
||||
.path;
|
||||
eventDataPath = [eventDataPath stringByAppendingPathComponent:@"gdt_event_data"];
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:eventDataPath isDirectory:NULL]) {
|
||||
NSError *error;
|
||||
[[NSFileManager defaultManager] createDirectoryAtPath:eventDataPath
|
||||
withIntermediateDirectories:YES
|
||||
attributes:0
|
||||
error:&error];
|
||||
GDTCORAssert(error == nil, @"Creating the library data path failed: %@", error);
|
||||
}
|
||||
});
|
||||
return eventDataPath;
|
||||
}
|
||||
|
||||
+ (NSString *)libraryDataStoragePath {
|
||||
+ (NSString *)libraryDataPath {
|
||||
static NSString *libraryDataPath;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
@@ -90,85 +60,18 @@ NSString *const gGDTCORFlatFileStorageQoSTierPathKey = @"QoSTierPath";
|
||||
isDirectory:YES]
|
||||
.path;
|
||||
libraryDataPath = [libraryDataPath stringByAppendingPathComponent:@"gdt_library_data"];
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:libraryDataPath isDirectory:NULL]) {
|
||||
NSError *error;
|
||||
[[NSFileManager defaultManager] createDirectoryAtPath:libraryDataPath
|
||||
withIntermediateDirectories:YES
|
||||
attributes:0
|
||||
error:&error];
|
||||
GDTCORAssert(error == nil, @"Creating the library data path failed: %@", error);
|
||||
}
|
||||
});
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:libraryDataPath isDirectory:NULL]) {
|
||||
NSError *error;
|
||||
[[NSFileManager defaultManager] createDirectoryAtPath:libraryDataPath
|
||||
withIntermediateDirectories:YES
|
||||
attributes:0
|
||||
error:&error];
|
||||
GDTCORAssert(error == nil, @"Creating the library data path failed: %@", error);
|
||||
}
|
||||
return libraryDataPath;
|
||||
}
|
||||
|
||||
+ (NSString *)pathForTarget:(GDTCORTarget)target
|
||||
eventID:(NSNumber *)eventID
|
||||
qosTier:(NSNumber *)qosTier
|
||||
mappingID:(NSString *)mappingID {
|
||||
return
|
||||
[NSString stringWithFormat:@"%@/%ld/%@.%@.%@", [GDTCORFlatFileStorage baseEventStoragePath],
|
||||
(long)target, eventID, qosTier, mappingID];
|
||||
}
|
||||
|
||||
+ (NSSet<NSString *> *)pathsForTarget:(GDTCORTarget)target
|
||||
eventIDs:(nullable NSSet<NSNumber *> *)eventIDs
|
||||
qosTiers:(nullable NSSet<NSNumber *> *)qosTiers
|
||||
mappingIDs:(nullable NSSet<NSString *> *)mappingIDs {
|
||||
NSMutableSet<NSString *> *paths = [[NSMutableSet alloc] init];
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSString *targetPath = [NSString
|
||||
stringWithFormat:@"%@/%ld", [GDTCORFlatFileStorage baseEventStoragePath], (long)target];
|
||||
NSError *error;
|
||||
NSArray<NSString *> *dirPaths = [fileManager contentsOfDirectoryAtPath:targetPath error:&error];
|
||||
if (error) {
|
||||
GDTCORLogDebug(@"There was an error reading the contents of the target path: %@", error);
|
||||
return paths;
|
||||
}
|
||||
BOOL checkingIDs = eventIDs.count > 0;
|
||||
BOOL checkingQosTiers = qosTiers.count > 0;
|
||||
BOOL checkingMappingIDs = mappingIDs.count > 0;
|
||||
BOOL checkingAnything = checkingIDs == NO && checkingQosTiers == NO && checkingMappingIDs == NO;
|
||||
for (NSString *path in dirPaths) {
|
||||
if (checkingAnything) {
|
||||
[paths addObject:path];
|
||||
continue;
|
||||
}
|
||||
NSString *filename = [path lastPathComponent];
|
||||
NSArray<NSString *> *components = [filename componentsSeparatedByString:@"."];
|
||||
if (components.count != 3) {
|
||||
GDTCORLogDebug(@"There was an error reading the filename components: %@", components);
|
||||
[[NSFileManager defaultManager] removeItemAtPath:path error:nil];
|
||||
continue;
|
||||
}
|
||||
NSNumber *eventID = @(components[0].integerValue);
|
||||
NSNumber *qosTier = @(components[1].integerValue);
|
||||
NSString *mappingID = components[2];
|
||||
if (eventID == nil || qosTier == nil) {
|
||||
GDTCORLogDebug(@"There was an error parsing the filename components: %@", components);
|
||||
[[NSFileManager defaultManager] removeItemAtPath:path error:nil];
|
||||
continue;
|
||||
}
|
||||
NSNumber *eventIDMatch = checkingIDs ? @([eventIDs containsObject:eventID]) : nil;
|
||||
NSNumber *qosTierMatch = checkingQosTiers ? @([qosTiers containsObject:qosTier]) : nil;
|
||||
NSNumber *mappingIDMatch = checkingMappingIDs ? @([mappingIDs containsObject:mappingID]) : nil;
|
||||
if ((eventIDMatch == nil || eventIDMatch.boolValue) &&
|
||||
(qosTierMatch == nil || qosTierMatch.boolValue) &&
|
||||
(mappingIDMatch == nil || mappingIDMatch.boolValue)) {
|
||||
[paths addObject:path];
|
||||
}
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
|
||||
+ (NSArray<NSString *> *)searchPathsWithEventSelector:(GDTCORStorageEventSelector *)eventSelector {
|
||||
NSSet *searchPaths = [GDTCORFlatFileStorage pathsForTarget:eventSelector.selectedTarget
|
||||
eventIDs:eventSelector.selectedEventIDs
|
||||
qosTiers:eventSelector.selectedQosTiers
|
||||
mappingIDs:eventSelector.selectedMappingIDs];
|
||||
return [searchPaths allObjects];
|
||||
}
|
||||
|
||||
+ (instancetype)sharedInstance {
|
||||
static GDTCORFlatFileStorage *sharedStorage;
|
||||
static dispatch_once_t onceToken;
|
||||
@@ -311,7 +214,7 @@ NSString *const gGDTCORFlatFileStorageQoSTierPathKey = @"QoSTierPath";
|
||||
onComplete:
|
||||
(nonnull void (^)(NSData *_Nullable, NSError *_Nullable error))onComplete {
|
||||
dispatch_async(_storageQueue, ^{
|
||||
NSString *dataPath = [[[self class] libraryDataStoragePath] stringByAppendingPathComponent:key];
|
||||
NSString *dataPath = [[[self class] libraryDataPath] stringByAppendingPathComponent:key];
|
||||
NSError *error;
|
||||
NSData *data = [NSData dataWithContentsOfFile:dataPath options:0 error:&error];
|
||||
if (onComplete) {
|
||||
@@ -322,7 +225,7 @@ NSString *const gGDTCORFlatFileStorageQoSTierPathKey = @"QoSTierPath";
|
||||
|
||||
- (void)storeLibraryData:(NSData *)data
|
||||
forKey:(nonnull NSString *)key
|
||||
onComplete:(nullable void (^)(NSError *_Nullable error))onComplete {
|
||||
onComplete:(nonnull void (^)(NSError *_Nullable error))onComplete {
|
||||
if (!data || data.length <= 0) {
|
||||
if (onComplete) {
|
||||
onComplete([NSError errorWithDomain:NSInternalInconsistencyException code:-1 userInfo:nil]);
|
||||
@@ -331,7 +234,7 @@ NSString *const gGDTCORFlatFileStorageQoSTierPathKey = @"QoSTierPath";
|
||||
}
|
||||
dispatch_async(_storageQueue, ^{
|
||||
NSError *error;
|
||||
NSString *dataPath = [[[self class] libraryDataStoragePath] stringByAppendingPathComponent:key];
|
||||
NSString *dataPath = [[[self class] libraryDataPath] stringByAppendingPathComponent:key];
|
||||
[data writeToFile:dataPath options:NSDataWritingAtomic error:&error];
|
||||
if (onComplete) {
|
||||
onComplete(error);
|
||||
@@ -343,7 +246,7 @@ NSString *const gGDTCORFlatFileStorageQoSTierPathKey = @"QoSTierPath";
|
||||
onComplete:(nonnull void (^)(NSError *_Nullable error))onComplete {
|
||||
dispatch_async(_storageQueue, ^{
|
||||
NSError *error;
|
||||
NSString *dataPath = [[[self class] libraryDataStoragePath] stringByAppendingPathComponent:key];
|
||||
NSString *dataPath = [[[self class] libraryDataPath] stringByAppendingPathComponent:key];
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:dataPath]) {
|
||||
[[NSFileManager defaultManager] removeItemAtPath:dataPath error:&error];
|
||||
if (onComplete) {
|
||||
@@ -353,61 +256,6 @@ NSString *const gGDTCORFlatFileStorageQoSTierPathKey = @"QoSTierPath";
|
||||
});
|
||||
}
|
||||
|
||||
- (BOOL)hasEventsForTarget:(GDTCORTarget)target {
|
||||
// TODO(mikehaney24): Increase the performance of this call.
|
||||
GDTCORStorageEventSelector *eventSelector =
|
||||
[[GDTCORStorageEventSelector alloc] initWithTarget:target
|
||||
eventIDs:nil
|
||||
mappingIDs:nil
|
||||
qosTiers:nil];
|
||||
id<GDTCORStorageEventIterator> iter = [self iteratorWithSelector:eventSelector];
|
||||
return [iter nextEvent] != nil;
|
||||
}
|
||||
|
||||
- (nullable id<GDTCORStorageEventIterator>)iteratorWithSelector:
|
||||
(nonnull GDTCORStorageEventSelector *)eventSelector {
|
||||
__block GDTCORFlatFileStorageIterator *iterator;
|
||||
dispatch_sync(_storageQueue, ^{
|
||||
NSArray<NSString *> *searchPaths =
|
||||
[GDTCORFlatFileStorage searchPathsWithEventSelector:eventSelector];
|
||||
iterator.eventFiles = searchPaths;
|
||||
});
|
||||
return iterator;
|
||||
}
|
||||
|
||||
- (void)purgeEventsFromBefore:(GDTCORClock *)beforeSnapshot
|
||||
onComplete:(void (^)(NSError *_Nullable error))onComplete {
|
||||
// TODO(mikehaney24): Figure out how we're going to deal with this.
|
||||
}
|
||||
|
||||
- (void)storageSizeWithCallback:(void (^)(uint64_t storageSize))onComplete {
|
||||
dispatch_async(_storageQueue, ^{
|
||||
unsigned long long totalBytes = 0;
|
||||
NSString *eventDataPath = [GDTCORFlatFileStorage baseEventStoragePath];
|
||||
NSString *libraryDataPath = [GDTCORFlatFileStorage libraryDataStoragePath];
|
||||
NSDirectoryEnumerator *enumerator =
|
||||
[[NSFileManager defaultManager] enumeratorAtPath:eventDataPath];
|
||||
while ([enumerator nextObject]) {
|
||||
NSFileAttributeType fileType = enumerator.fileAttributes[NSFileType];
|
||||
if ([fileType isEqual:NSFileTypeRegular]) {
|
||||
NSNumber *fileSize = enumerator.fileAttributes[NSFileSize];
|
||||
totalBytes += fileSize.unsignedLongLongValue;
|
||||
}
|
||||
}
|
||||
enumerator = [[NSFileManager defaultManager] enumeratorAtPath:libraryDataPath];
|
||||
while ([enumerator nextObject]) {
|
||||
NSFileAttributeType fileType = enumerator.fileAttributes[NSFileType];
|
||||
if ([fileType isEqual:NSFileTypeRegular]) {
|
||||
NSNumber *fileSize = enumerator.fileAttributes[NSFileSize];
|
||||
totalBytes += fileSize.unsignedLongLongValue;
|
||||
}
|
||||
}
|
||||
if (onComplete) {
|
||||
onComplete(totalBytes);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - Private helper methods
|
||||
|
||||
/** Saves the event's dataObject to a file using NSData mechanisms.
|
||||
@@ -462,8 +310,8 @@ NSString *const gGDTCORFlatFileStorageQoSTierPathKey = @"QoSTierPath";
|
||||
|
||||
- (void)appWillBackground:(GDTCORApplication *)app {
|
||||
dispatch_async(_storageQueue, ^{
|
||||
// Immediately request a background task to run until the end of the current queue of work,
|
||||
// and cancel it once the work is done.
|
||||
// Immediately request a background task to run until the end of the current queue of work, and
|
||||
// cancel it once the work is done.
|
||||
__block GDTCORBackgroundIdentifier bgID =
|
||||
[app beginBackgroundTaskWithName:@"GDTStorage"
|
||||
expirationHandler:^{
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "GDTCORLibrary/Private/GDTCORFlatFileStorageIterator.h"
|
||||
|
||||
#import <GoogleDataTransport/GDTCORConsoleLogger.h>
|
||||
#import <GoogleDataTransport/GDTCOREvent.h>
|
||||
|
||||
@implementation GDTCORFlatFileStorageIterator {
|
||||
/** The current eventFiles array index, incremented in -nextEvent. */
|
||||
NSInteger _currentIndex;
|
||||
}
|
||||
|
||||
- (instancetype)initWithTarget:(GDTCORTarget)target queue:(dispatch_queue_t)queue {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_queue = queue;
|
||||
_target = target;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (nullable GDTCOREvent *)nextEvent {
|
||||
if (_currentIndex == -1) {
|
||||
return nil;
|
||||
}
|
||||
if (!_eventFiles) {
|
||||
GDTCORLogDebug(@"%@", @"eventFiles property not set, so -nextEvent will be nil.");
|
||||
return nil;
|
||||
}
|
||||
dispatch_queue_t queue = _queue;
|
||||
if (!queue) {
|
||||
GDTCORLogDebug(@"%@", @"iterator queue was nil, so -nextEvent will be nil.");
|
||||
return nil;
|
||||
}
|
||||
__block GDTCOREvent *nextEvent;
|
||||
dispatch_sync(queue, ^{
|
||||
NSData *data = [NSData dataWithContentsOfFile:self->_eventFiles[self->_currentIndex]];
|
||||
if (data) {
|
||||
NSError *error;
|
||||
nextEvent = (GDTCOREvent *)GDTCORDecodeArchive([GDTCOREvent class], nil, data, &error);
|
||||
if (error || nextEvent == nil) {
|
||||
GDTCORLogDebug(@"Unarchiving an event failed: %@", error);
|
||||
nextEvent = nil;
|
||||
self->_currentIndex = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
return nextEvent;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "GDTCORLibrary/Public/GDTCORStorageEventSelector.h"
|
||||
|
||||
@implementation GDTCORStorageEventSelector
|
||||
|
||||
- (instancetype)initWithTarget:(GDTCORTarget)target
|
||||
eventIDs:(nullable NSSet<NSNumber *> *)eventIDs
|
||||
mappingIDs:(nullable NSSet<NSString *> *)mappingIDs
|
||||
qosTiers:(nullable NSSet<NSNumber *> *)qosTiers {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_selectedTarget = target;
|
||||
_selectedEventIDs = eventIDs;
|
||||
_selectedMappingIDs = mappingIDs;
|
||||
_selectedQosTiers = qosTiers;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -17,7 +17,6 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <GoogleDataTransport/GDTCORLifecycle.h>
|
||||
#import <GoogleDataTransport/GDTCORStorageEventSelector.h>
|
||||
#import <GoogleDataTransport/GDTCORStorageProtocol.h>
|
||||
|
||||
@class GDTCOREvent;
|
||||
@@ -25,14 +24,7 @@
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/** Manages the storage of events. This class is thread-safe.
|
||||
*
|
||||
* Event files will be stored as follows:
|
||||
* <app cache>/gdt_event_data/<target>/<eventID>.<qosTier>.<mappingID>
|
||||
*
|
||||
* Library data will be stored as follows:
|
||||
* <app cache>/gdt_library_data/<key of library data>
|
||||
*/
|
||||
/** Manages the storage of events. This class is thread-safe. */
|
||||
@interface GDTCORFlatFileStorage
|
||||
: NSObject <NSSecureCoding, GDTCORStorageProtocol, GDTCORLifecycleProtocol>
|
||||
|
||||
@@ -62,49 +54,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
+ (NSString *)archivePath;
|
||||
|
||||
/** Returns the base directory under which all events will be stored.
|
||||
*
|
||||
* @return The base directory under which all events will be stored.
|
||||
*/
|
||||
+ (NSString *)baseEventStoragePath;
|
||||
|
||||
/** Returns the base directory under which all library data will be stored.
|
||||
*
|
||||
* @return The base directory under which all library data will be stored.
|
||||
*/
|
||||
+ (NSString *)libraryDataStoragePath;
|
||||
|
||||
/** Returns a constructed storage path based on the given values. This path may not exist.
|
||||
*
|
||||
* @param target The target, which is necessary to be given a path.
|
||||
* @param eventID The eventID.
|
||||
* @param qosTier The qosTier.
|
||||
* @param mappingID The mappingID.
|
||||
* @return The path representing the combination of the given parameters.
|
||||
*/
|
||||
+ (NSString *)pathForTarget:(GDTCORTarget)target
|
||||
eventID:(NSNumber *)eventID
|
||||
qosTier:(NSNumber *)qosTier
|
||||
mappingID:(NSString *)mappingID;
|
||||
|
||||
/** Returns extant paths that match all of the given parameters.
|
||||
*
|
||||
* @param eventIDs The list of eventIDs to look for, or nil for any.
|
||||
* @param qosTiers The list of qosTiers to look for, or nil for any.
|
||||
* @param mappingIDs The list of mappingIDs to look for, or nil for any.
|
||||
*/
|
||||
+ (NSSet<NSString *> *)pathsForTarget:(GDTCORTarget)target
|
||||
eventIDs:(nullable NSSet<NSNumber *> *)eventIDs
|
||||
qosTiers:(nullable NSSet<NSNumber *> *)qosTiers
|
||||
mappingIDs:(nullable NSSet<NSString *> *)mappingIDs;
|
||||
|
||||
/** Returns a list of paths that will contain events for the given event selector.
|
||||
*
|
||||
* @param eventSelector The event selector to process.
|
||||
* @return A list of paths that exist and could contain events.
|
||||
*/
|
||||
+ (NSArray<NSString *> *)searchPathsWithEventSelector:(GDTCORStorageEventSelector *)eventSelector;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <GoogleDataTransport/GDTCORStorageProtocol.h>
|
||||
|
||||
/** The flat file storage iterator. */
|
||||
@interface GDTCORFlatFileStorageIterator : NSObject <GDTCORStorageEventIterator>
|
||||
|
||||
/** The queue on which the iterator will run. */
|
||||
@property(nonatomic, readonly) dispatch_queue_t queue;
|
||||
|
||||
/** The target the iterator will work on. */
|
||||
@property(nonatomic, readonly) GDTCORTarget target;
|
||||
|
||||
/** The list of event files to iterate over. This should be set before calling -nextEvent. */
|
||||
@property(nonatomic) NSArray<NSString *> *eventFiles;
|
||||
|
||||
@end
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <GoogleDataTransport/GDTCORTargets.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/** This class enables the finding of events by matching events with the properties of this class.
|
||||
*/
|
||||
@interface GDTCORStorageEventSelector : NSObject
|
||||
|
||||
/** The target to find events for. Required. */
|
||||
@property(readonly, nonatomic) GDTCORTarget selectedTarget;
|
||||
|
||||
/** Finds a specific event. */
|
||||
@property(nullable, readonly, nonatomic) NSSet<NSNumber *> *selectedEventIDs;
|
||||
|
||||
/** Finds all events of a mappingID. */
|
||||
@property(nullable, readonly, nonatomic) NSSet<NSString *> *selectedMappingIDs;
|
||||
|
||||
/** Finds all events matching the qosTiers in this list. */
|
||||
@property(nullable, readonly, nonatomic) NSSet<NSNumber *> *selectedQosTiers;
|
||||
|
||||
/** Instantiates an event selector.
|
||||
*
|
||||
* @param target The selected target.
|
||||
* @param eventIDs Optional param to find an event matching this eventID.
|
||||
* @param mappingIDs Optional param to find events matching this mappingID.
|
||||
* @param qosTiers Optional param to find events matching the given QoS tiers.
|
||||
* @return An immutable event selector instance.
|
||||
*/
|
||||
- (instancetype)initWithTarget:(GDTCORTarget)target
|
||||
eventIDs:(nullable NSSet<NSNumber *> *)eventIDs
|
||||
mappingIDs:(nullable NSSet<NSString *> *)mappingIDs
|
||||
qosTiers:(nullable NSSet<NSNumber *> *)qosTiers;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -17,35 +17,12 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <GoogleDataTransport/GDTCORLifecycle.h>
|
||||
#import <GoogleDataTransport/GDTCORStorageEventSelector.h>
|
||||
#import <GoogleDataTransport/GDTCORTargets.h>
|
||||
|
||||
@class GDTCOREvent;
|
||||
@class GDTCORClock;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/** Defines an iterator API for processing or fetching events. */
|
||||
@protocol GDTCORStorageEventIterator <NSObject>
|
||||
|
||||
@required
|
||||
|
||||
/** Initializes an iterator instance with the given target and queue.
|
||||
*
|
||||
* @param target The target for which the events are stored.
|
||||
* @param queue The queue on which the iterator should run.
|
||||
* @return An iterator instance.
|
||||
*/
|
||||
- (instancetype)initWithTarget:(GDTCORTarget)target queue:(dispatch_queue_t)queue;
|
||||
|
||||
/** Returns the next event or nil if there are no more events to iterate over.
|
||||
*
|
||||
* @return A GDTCOREvent instance or nil if the iterator has iterated through all the events.
|
||||
*/
|
||||
- (nullable GDTCOREvent *)nextEvent;
|
||||
|
||||
@end
|
||||
|
||||
/** Defines the interface a storage subsystem is expected to implement. */
|
||||
@protocol GDTCORStorageProtocol <NSObject, GDTCORLifecycleProtocol>
|
||||
|
||||
@@ -70,7 +47,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
- (void)storeLibraryData:(NSData *)data
|
||||
forKey:(NSString *)key
|
||||
onComplete:(nullable void (^)(NSError *_Nullable error))onComplete;
|
||||
onComplete:(void (^)(NSError *_Nullable error))onComplete;
|
||||
|
||||
/** Retrieves the stored data for the given key.
|
||||
*
|
||||
@@ -88,34 +65,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
- (void)removeLibraryDataForKey:(NSString *)key
|
||||
onComplete:(void (^)(NSError *_Nullable error))onComplete;
|
||||
|
||||
/** Returns YES if some events have been stored for the given target, NO otherwise.
|
||||
*
|
||||
* @return YES if the storage contains events for the given target, NO otherwise.
|
||||
*/
|
||||
- (BOOL)hasEventsForTarget:(GDTCORTarget)target;
|
||||
|
||||
/** Returns an iterator object that can be used to iterate over events that match the eventSelector.
|
||||
*
|
||||
* @param eventSelector The event selector to match events with.
|
||||
* @return An iterator instance.
|
||||
*/
|
||||
- (nullable id<GDTCORStorageEventIterator>)iteratorWithSelector:
|
||||
(GDTCORStorageEventSelector *)eventSelector;
|
||||
|
||||
/** Removes events from before the given time.
|
||||
*
|
||||
* @param beforeSnapshot The time at which all events prior should be deleted.
|
||||
* @param onComplete The callback that will be invoked when deleting events is complete.
|
||||
*/
|
||||
- (void)purgeEventsFromBefore:(GDTCORClock *)beforeSnapshot
|
||||
onComplete:(void (^)(NSError *_Nullable error))onComplete;
|
||||
|
||||
/** Calculates and returns the total disk size that this storage consumes.
|
||||
*
|
||||
* @param onComplete The callback that will be invoked once storage size calculation is complete.
|
||||
*/
|
||||
- (void)storageSizeWithCallback:(void (^)(uint64_t storageSize))onComplete;
|
||||
|
||||
@end
|
||||
|
||||
/** Retrieves the storage instance for the given target.
|
||||
|
||||
@@ -25,18 +25,10 @@
|
||||
dispatch_sync(self.storageQueue, ^{
|
||||
[self.targetToEventSet removeAllObjects];
|
||||
[self.storedEvents removeAllObjects];
|
||||
[[NSFileManager defaultManager] removeItemAtPath:[GDTCORFlatFileStorage archivePath] error:nil];
|
||||
[[NSFileManager defaultManager] removeItemAtPath:[GDTCORFlatFileStorage baseEventStoragePath]
|
||||
error:nil];
|
||||
[[NSFileManager defaultManager] removeItemAtPath:[GDTCORFlatFileStorage libraryDataStoragePath]
|
||||
error:nil];
|
||||
NSError *error;
|
||||
[[NSFileManager defaultManager] removeItemAtPath:[GDTCORFlatFileStorage archivePath]
|
||||
error:&error];
|
||||
});
|
||||
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
||||
[[GDTCORFlatFileStorage sharedInstance] storageSizeWithCallback:^(uint64_t storageSize) {
|
||||
NSAssert(storageSize == 0, @"Storage should contain nothing after a reset");
|
||||
dispatch_semaphore_signal(sema);
|
||||
}];
|
||||
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
- (void)storeLibraryData:(NSData *)data
|
||||
forKey:(nonnull NSString *)key
|
||||
onComplete:(nullable void (^)(NSError *_Nullable error))onComplete {
|
||||
onComplete:(nonnull void (^)(NSError *_Nullable error))onComplete {
|
||||
if (onComplete) {
|
||||
onComplete(nil);
|
||||
}
|
||||
@@ -51,20 +51,4 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)hasEventsForTarget:(GDTCORTarget)target {
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (nullable id<GDTCORStorageEventIterator>)iteratorWithSelector:
|
||||
(nonnull GDTCORStorageEventSelector *)eventSelector {
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)purgeEventsFromBefore:(GDTCORClock *)beforeSnapshot
|
||||
onComplete:(void (^)(NSError *_Nullable error))onComplete {
|
||||
}
|
||||
|
||||
- (void)storageSizeWithCallback:(void (^)(uint64_t storageSize))onComplete {
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -525,77 +525,6 @@ static NSInteger target = kGDTCORTargetCCT;
|
||||
[self waitForExpectations:@[ expectation ] timeout:10.0];
|
||||
}
|
||||
|
||||
/** Tests that -pathForTarget:qosTier:mappingID: returns the correctly structured path. */
|
||||
- (void)testPathsForTargetEventIDQoSTierMappingID {
|
||||
// TODO(mikehaney24): Complete below tests once events are being saved to disk.
|
||||
|
||||
// Store some predictably generated events across > 1 target.
|
||||
|
||||
// Search for all events (by target).
|
||||
|
||||
// Search for events by eventID.
|
||||
|
||||
// Search for events by qosTier.
|
||||
|
||||
// Search for events by mappingID.
|
||||
|
||||
// Search for events by eventID and qosTier.
|
||||
|
||||
// Search for events by qosTier and mappingID.
|
||||
}
|
||||
|
||||
/** Tests that searchPathsWithEventSelector: returns the appropriate event search paths. */
|
||||
- (void)testSearchPathsWithEventSelector {
|
||||
// TODO(mikehaney24): Implement when events are actually being stored.
|
||||
}
|
||||
|
||||
/** Tests hasEventsForTarget: returns YES when events are stored and NO otherwise. */
|
||||
- (void)testHasEventsForTarget {
|
||||
XCTAssertFalse([[GDTCORFlatFileStorage sharedInstance] hasEventsForTarget:kGDTCORTargetTest]);
|
||||
|
||||
// TODO(mikehaney24): Store events and test for YES.
|
||||
}
|
||||
|
||||
/** Tests -iteratorWithSelector produces a usable iterator. */
|
||||
- (void)testIteratorWithSelector {
|
||||
GDTCORStorageEventSelector *eventSelector =
|
||||
[[GDTCORStorageEventSelector alloc] initWithTarget:kGDTCORTargetTest
|
||||
eventIDs:nil
|
||||
mappingIDs:nil
|
||||
qosTiers:nil];
|
||||
id<GDTCORStorageEventIterator> iter =
|
||||
[[GDTCORFlatFileStorage sharedInstance] iteratorWithSelector:eventSelector];
|
||||
XCTAssertNil([iter nextEvent]);
|
||||
|
||||
// TODO(mikehaney24): Store events and test.
|
||||
}
|
||||
|
||||
/** Tests -purgeEventsFromBefore:onComplete: removes prior to an arbitrary time. */
|
||||
- (void)testPurgeEvents {
|
||||
// TODO(mikehaney24): Complete when purge events is implemented.
|
||||
}
|
||||
|
||||
/** Tests that the size of the storage is returned accurately. */
|
||||
- (void)testStorageSizeWithCallback {
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:@"storageSize complete"];
|
||||
[[GDTCORFlatFileStorage sharedInstance] storageSizeWithCallback:^(uint64_t storageSize) {
|
||||
XCTAssertEqual(storageSize, 0);
|
||||
[expectation fulfill];
|
||||
}];
|
||||
[self waitForExpectations:@[ expectation ] timeout:10.0];
|
||||
|
||||
expectation = [self expectationWithDescription:@"storageSize complete"];
|
||||
NSData *data = [@"this is a test" dataUsingEncoding:NSUTF8StringEncoding];
|
||||
[[GDTCORFlatFileStorage sharedInstance] storeLibraryData:data forKey:@"testKey" onComplete:nil];
|
||||
[[GDTCORFlatFileStorage sharedInstance] storageSizeWithCallback:^(uint64_t storageSize) {
|
||||
XCTAssertEqual(storageSize, data.length);
|
||||
[expectation fulfill];
|
||||
}];
|
||||
[self waitForExpectations:@[ expectation ] timeout:10.0];
|
||||
|
||||
// TODO(mikehaney24): Complete this test when events are actually being stored.
|
||||
}
|
||||
|
||||
/** Tests migration from v1 of the storage format to v2. */
|
||||
- (void)testMigrationFromOldVersion {
|
||||
static NSString *base64EncodedArchive =
|
||||
|
||||
Reference in new issue
Block a user