yy20111011659 / route-me

Automatically exported from code.google.com/p/route-me
0 stars 0 forks source link

Patches for read-only databases #122

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
Here are some patches I made to implement read-only databases.

The purpose is to package an iPhone app with a built-in resource, a
read-only map tile cache, which will be used as efficiently as possible
(i.e. no writing the last used date, or counting the number of items to see
if it needs purging), and then have another writable database for caching
tiles that aren't built into the app. 

The routeme.plist defines three caches: a memory cache, my read-only cache
with useCachesDirectory false (so it comes from Documents), and a regular
database cache with useCachesDirectory true (so it comes from Caches). 

I store the map cache as an app resource, and make a symbolic link from the
documents directory to the app resource, when the app starts up.

It would be nice to be able to configure the cache directories somehow in
the routeme.plist instead of messing around with symbolic links, but I
haven't done that yet.

One issue I'd like to understand better: Will the tiles from the read-only
cache trickle down into the writable cache, wasting space? Is there a way
to prevent that? 

For some reason I had to put a cast of the id cfg to NSDictionary *, to
make it work, but I don't understand why...

//          NSString* type = [cfg valueForKey:@"type"];
            NSDictionary *d = (NSDictionary *)cfg; // Don added this cast, which
makes it work!
            NSString* type = [d valueForKey:@"type"];

Here are the diffs for read-only databases.

bash-3.2$ svn diff
Index: MapView/Map/RMTileCache.m
===================================================================
--- MapView/Map/RMTileCache.m   (revision 577)
+++ MapView/Map/RMTileCache.m   (working copy)
@@ -69,8 +69,10 @@
        id<RMTileCache> newCache = nil;

        @try {
-           NSString* type = [cfg valueForKey:@"type"];
-           
+//         NSString* type = [cfg valueForKey:@"type"];
+           NSDictionary *d = (NSDictionary *)cfg; // Don added this cast, which
makes it work!
+           NSString* type = [d valueForKey:@"type"];
+
            /// \bug magic string literals
            if ([@"memory-cache" isEqualToString: type]) 
                newCache = [self newMemoryCacheWithConfig: cfg];
@@ -169,7 +171,8 @@
    /// \bug magic numbers
    NSUInteger capacity = 1000;
    NSUInteger minimalPurge = capacity / 10;
-   
+   BOOL readOnly = NO;
+
    NSNumber* capacityNumber = [cfg objectForKey:@"capacity"];
    if (capacityNumber!=nil) {
        NSInteger value = [capacityNumber intValue];
@@ -202,9 +205,15 @@
        }
    }

+   NSNumber* readOnlyNumber = [cfg objectForKey:@"readOnly"];
+   if (readOnlyNumber != nil) {
+       readOnly = [readOnlyNumber boolValue];
+   }
+   
    RMDatabaseCache* dbCache = [[RMDatabaseCache alloc] 
                                initWithTileSource: theTileSource 
                                usingCacheDir: useCacheDir
+                               readOnly: readOnly
                                ];

    [dbCache setCapacity: capacity];
Index: MapView/Map/RMDatabaseCache.h
===================================================================
--- MapView/Map/RMDatabaseCache.h   (revision 577)
+++ MapView/Map/RMDatabaseCache.h   (working copy)
@@ -36,13 +36,14 @@
    RMCachePurgeStrategy purgeStrategy;
    NSUInteger capacity;
    NSUInteger minimalPurge;
+   BOOL readOnly;
 }

 @property (retain) NSString* databasePath;

 + (NSString*)dbPathForTileSource: (id<RMTileSource>) source usingCacheDir:
(BOOL) useCacheDir;
 -(id) initWithDatabase: (NSString*)path;
--(id) initWithTileSource: (id<RMTileSource>) source usingCacheDir: (BOOL)
useCacheDir;
+-(id) initWithTileSource: (id<RMTileSource>) source usingCacheDir: (BOOL)
useCacheDir readOnly: (BOOL) isReadOnly;

 -(void) setPurgeStrategy: (RMCachePurgeStrategy) theStrategy;
 -(void) setCapacity: (NSUInteger) theCapacity;
Index: MapView/Map/RMDatabaseCache.m
===================================================================
--- MapView/Map/RMDatabaseCache.m   (revision 577)
+++ MapView/Map/RMDatabaseCache.m   (working copy)
@@ -78,8 +78,9 @@
    return self;    
 }

--(id) initWithTileSource: (id<RMTileSource>) source usingCacheDir: (BOOL)
useCacheDir
+-(id) initWithTileSource: (id<RMTileSource>) source usingCacheDir: (BOOL)
useCacheDir readOnly: (BOOL) isReadOnly
 {
+   readOnly = isReadOnly;
    return [self initWithDatabase:[RMDatabaseCache dbPathForTileSource:source
usingCacheDir: useCacheDir]];
 }

@@ -109,6 +110,10 @@

 -(void)addTile: (RMTile)tile WithImage: (RMTileImage*)image
 {
+   if (readOnly) {
+       return;
+   }
+
    // The tile probably hasn't loaded any data yet... we must be patient.
    // However, if the image is already loaded we probably don't need to
cache it.

@@ -124,6 +129,10 @@

 -(void) addImageData: (NSNotification *)notification
 {
+   if (readOnly) {
+       return;
+   }
+
    NSData *data = [[notification userInfo] objectForKey:@"data"];
    /// \bug magic string literals
    RMTileImage *image = (RMTileImage*)[notification object];
@@ -160,7 +169,7 @@
        if (data == nil)
            return nil;

-       if (capacity != 0 && purgeStrategy == RMCachePurgeStrategyLRU) {
+       if (!readOnly && capacity != 0 && purgeStrategy ==
RMCachePurgeStrategyLRU) {
            [dao touchTile: RMTileKey(tile) withDate: [NSDate date]];
        }

@@ -189,6 +198,9 @@

 -(void) removeAllCachedImages 
 {
+   if (readOnly) {
+       return;
+   }
    [dao removeAllCachedImages];
 }

Original issue reported on code.google.com by simhac...@gmail.com on 10 Nov 2009 at 8:05