We should not keep the cacheURL local ivar. It could change during a  
run. E.g. after a Save As, the original cached index belongs to the  
file at the old location rather than the current document, and the  
cached index should be written to a different location. So there  
should be a map from database URL (or alias) to cached index URL.  
Possibly in a separate plist file. This way the old cached index can  
be found back or overwritten if required.

Christiaan


On 17 Jan 2008, at 9:19 PM, [EMAIL PROTECTED] wrote:

> Revision: 12540
>           http://bibdesk.svn.sourceforge.net/bibdesk/? 
> rev=12540&view=rev
> Author:   amaxwell
> Date:     2008-01-17 12:19:13 -0800 (Thu, 17 Jan 2008)
>
> Log Message:
> -----------
> Changes to disk caching.  Save to ~/Library/Caches, introspect  
> caches to find the correct document.  Seems fast enough.
>
> Save index on index -cancel, which is sent when the window closes.   
> Also register for app terminate notifications.  Use the condition  
> lock to save only after the worker thread exits.
>
> Modified Paths:
> --------------
>     trunk/bibdesk/BDSKFileContentSearchController.m
>     trunk/bibdesk/BDSKFileSearchIndex.h
>     trunk/bibdesk/BDSKFileSearchIndex.m
>
> Modified: trunk/bibdesk/BDSKFileContentSearchController.m
> ===================================================================
> --- trunk/bibdesk/BDSKFileContentSearchController.m   2008-01-17  
> 19:19:57 UTC (rev 12539)
> +++ trunk/bibdesk/BDSKFileContentSearchController.m   2008-01-17  
> 20:19:13 UTC (rev 12540)
> @@ -73,16 +73,7 @@
>      NSParameterAssert([aDocument conformsToProtocol:@protocol 
> (BDSKSearchContentView)]);
>      [self setDocument:aDocument];
>
> -    // @@ temporary: this is just a temporary setup for testing  
> search index caching
> -    NSURL *cacheURL = nil;
> -    if ([[NSUserDefaults standardUserDefaults]  
> boolForKey:@"BDSKShouldCacheFileSearchIndexKey"]) {
> -        NSString *cachePath;
> -        cachePath = [[[[self document] fileName]  
> stringByDeletingPathExtension]  
> stringByAppendingPathExtension:@"bdskindex"];
> -        if ([[NSFileManager defaultManager]  
> fileExistsAtPath:cachePath])
> -            cacheURL = [NSURL fileURLWithPath:cachePath];
> -    }
> -
> -    searchIndex = [[BDSKFileSearchIndex alloc]  
> initWithDocument:aDocument cacheURL:cacheURL];
> +    searchIndex = [[BDSKFileSearchIndex alloc]  
> initWithDocument:aDocument];
>      search = [[BDSKFileSearch alloc] initWithIndex:searchIndex  
> delegate:self];
>      searchFieldDidEndEditing = NO;
>
> @@ -415,16 +406,11 @@
>      // extra safety here; make sure the index stops messaging the  
> search object now
>      [searchIndex setDelegate:nil];
>
> -    // @@ temporary: this is just a temporary setup for testing  
> search index caching
> -    NSString *cachePath = nil;
> -    if ([[NSUserDefaults standardUserDefaults]  
> boolForKey:@"BDSKShouldCacheFileSearchIndexKey"])
> -        cachePath = [[[[self document] fileName]  
> stringByDeletingPathExtension]  
> stringByAppendingPathExtension:@"bdskindex"];
> +    // let the index know the document's location so it can cache  
> the index to disk
> +    [searchIndex setDocumentURL:[[self document] fileURL]];
>
> -    // stops the search index runloop so it will release the document
> -    if (cachePath)
> -        [searchIndex closeIndexAndCacheToURL:[NSURL  
> fileURLWithPath:cachePath]];
> -    else
> -        [searchIndex cancel];
> +    // stops the search index runloop
> +    [searchIndex cancel];
>      [searchIndex release];
>      searchIndex = nil;
>  }
>
> Modified: trunk/bibdesk/BDSKFileSearchIndex.h
> ===================================================================
> --- trunk/bibdesk/BDSKFileSearchIndex.h       2008-01-17 19:19:57 UTC  
> (rev 12539)
> +++ trunk/bibdesk/BDSKFileSearchIndex.h       2008-01-17 20:19:13 UTC  
> (rev 12540)
> @@ -60,6 +60,8 @@
>      CFMutableDataRef indexData;
>      NSMutableDictionary *itemInfos;
>      NSMutableDictionary *signatures;
> +    NSURL *documentURL;
> +    NSURL *indexCacheURL;
>      id delegate;
>
>      BDSKThreadSafeMutableArray *notificationQueue;
> @@ -72,7 +74,6 @@
>
>  // aDocument must respond to -publications; this should generally  
> be called on the main thread
>  - (id)initWithDocument:(id)aDocument;
> -- (id)initWithDocument:(id)aDocument cacheURL:(NSURL *)cacheURL;
>
>  // Warning:  it is /not/ safe to write to this SKIndexRef  
> directly; use it only for reading.
>  - (SKIndexRef)index;
> @@ -82,12 +83,11 @@
>  - (BOOL)isIndexing;
>  - (void)setDelegate:(id <BDSKFileSearchIndexDelegate>)anObject;
>  - (NSDictionary *)itemInfoForURL:(NSURL *)theURL;
> -- (NSData *)signatureForURL:(NSURL *)theURL;
>
>  // Poll this for progress bar updates during indexing
>  - (double)progressValue;
>
> -- (BOOL)closeIndexAndCacheToURL:(NSURL *)cacheURL;
> +- (void)setDocumentURL:(NSURL *)aURL;
>
>  @end
>
>
> Modified: trunk/bibdesk/BDSKFileSearchIndex.m
> ===================================================================
> --- trunk/bibdesk/BDSKFileSearchIndex.m       2008-01-17 19:19:57 UTC  
> (rev 12539)
> +++ trunk/bibdesk/BDSKFileSearchIndex.m       2008-01-17 20:19:13 UTC  
> (rev 12540)
> @@ -47,7 +47,7 @@
>
>  - (NSArray *)itemsToIndex:(NSArray *)items;
>  - (void)buildIndexForItems:(NSArray *)items;
> -- (void)indexFilesForItems:(NSArray *)items;
> +- (void)indexFilesForItems:(NSArray *)items  
> numberPreviouslyIndexed:(double)numberIndexed totalCount:(double) 
> totalObjectCount;
>  - (void)indexFilesForItem:(id)anItem;
>  - (void)runIndexThreadForItems:(NSArray *)items;
>  - (void)processNotification:(NSNotification *)note;
> @@ -55,28 +55,57 @@
>  - (void)handleDocDelItemNotification:(NSNotification *)note;
>  - (void)handleSearchIndexInfoChangedNotification:(NSNotification *) 
> note;
>  - (void)handleMachMessage:(void *)msg;
> +- (void)writeIndexToDisk;
>
>  @end
>
> +static NSString *cacheIndexFolder()
> +{
> +    static NSString *cacheFolder = nil;
> +    if (nil == cacheFolder) {
> +        cacheFolder = [NSSearchPathForDirectoriesInDomains 
> (NSCachesDirectory, NSUserDomainMask, YES) lastObject];
> +        cacheFolder = [cacheFolder stringByAppendingPathComponent: 
> [[NSBundle mainBundle] bundleIdentifier]];
> +        if (cacheFolder && [[NSFileManager defaultManager]  
> fileExistsAtPath:cacheFolder] == NO)
> +            [[NSFileManager defaultManager]  
> createDirectoryAtPath:cacheFolder attributes:nil];
> +        cacheFolder = [cacheFolder  
> stringByAppendingPathComponent:@"Search indexes"];
> +        if (cacheFolder && [[NSFileManager defaultManager]  
> fileExistsAtPath:cacheFolder] == NO)
> +            [[NSFileManager defaultManager]  
> createDirectoryAtPath:cacheFolder attributes:nil];
> +        cacheFolder = [cacheFolder copy];
> +    }
> +    return cacheFolder;
> +}
> +
> +// Read each cache file and see which one has a matching  
> documentURL.  If this gets too slow, we could save a plist mapping  
> URL -> UUID and use that instead.
> +static NSURL *copyIndexCacheURLForDocumentURL(NSURL *documentURL)
> +{
> +    NSCParameterAssert(nil != documentURL);
> +    NSString *cacheFolder = cacheIndexFolder();
> +    NSArray *existingIndexes = [[NSFileManager defaultManager]  
> directoryContentsAtPath:cacheFolder];
> +    existingIndexes = [existingIndexes pathsMatchingExtensions: 
> [NSArray arrayWithObject:@"bdskindex"]];
> +
> +    NSEnumerator *indexEnum = [existingIndexes objectEnumerator];
> +    NSString *path;
> +    NSURL *indexCacheURL = nil;
> +
> +    while ((path = [indexEnum nextObject]) && nil == indexCacheURL) {
> +        path = [cacheFolder stringByAppendingPathComponent:path];
> +        NSDictionary *cacheDict = [NSKeyedUnarchiver  
> unarchiveObjectWithFile:path];
> +        if ([[cacheDict objectForKey:@"documentURL"]  
> isEqual:documentURL])
> +            indexCacheURL = [[NSURL alloc] initFileURLWithPath:path];
> +    }
> +    return indexCacheURL;
> +}
> +
> +
>  @implementation BDSKFileSearchIndex
>
>  #define INDEX_STARTUP 1
>  #define INDEX_STARTUP_COMPLETE 2
> +#define INDEX_THREAD_WORKING 3
> +#define INDEX_THREAD_DONE 4
>
> -static inline NSData *sha1SignatureForURL(NSURL *aURL) {
> -    NSData *data = [[NSData alloc] initWithContentsOfURL:aURL];
> -    NSData *sha1Signature = [data sha1Signature];
> -    [data release];
> -    return sha1Signature;
> -}
> -
>  - (id)initWithDocument:(id)aDocument
>  {
> -    return [self initWithDocument:aDocument cacheURL:nil];
> -}
> -
> -- (id)initWithDocument:(id)aDocument cacheURL:(NSURL *)cacheURL
> -{
>      OBASSERT([NSThread inMainThread]);
>
>      self = [super init];
> @@ -87,8 +116,10 @@
>
>          index = NULL;
>
> -        if (cacheURL) {
> -            NSDictionary *cacheDict = [NSKeyedUnarchiver  
> unarchiveObjectWithFile:[cacheURL path]];
> +        // new document won't have a URL, so we'll have to wait  
> for the controller to set it
> +        indexCacheURL = [aDocument fileURL] ?  
> copyIndexCacheURLForDocumentURL([aDocument fileURL]) : nil;
> +        if (indexCacheURL) {
> +            NSDictionary *cacheDict = [NSKeyedUnarchiver  
> unarchiveObjectWithFile:[indexCacheURL path]];
>              indexData = (CFMutableDataRef)[[cacheDict  
> objectForKey:@"indexData"] mutableCopy];
>              if (indexData != NULL) {
>                  index = SKIndexOpenWithMutableData(indexData, NULL);
> @@ -99,6 +130,11 @@
>                      indexData = NULL;
>                  }
>              }
> +        } else {
> +            // Could use the doc name, but I keep different files  
> with the same name on shared and local volumes, and presumably  
> others do things that are just as weird.  This guarantees a unique  
> name, so we'll just introspect the caches when loading them.
> +            NSString *cachePath = [cacheIndexFolder()  
> stringByAppendingPathComponent:[[NSProcessInfo processInfo]  
> globallyUniqueString]];
> +            cachePath = [cachePath  
> stringByAppendingPathExtension:@"bdskindex"];
> +            indexCacheURL = [[NSURL alloc]  
> initFileURLWithPath:cachePath];
>          }
>
>          if (index == NULL) {
> @@ -113,6 +149,7 @@
>          [nc addObserver:self selector:handler  
> name:BDSKFileSearchIndexInfoChangedNotification object:aDocument];
>          [nc addObserver:self selector:handler  
> name:BDSKDocAddItemNotification object:aDocument];
>          [nc addObserver:self selector:handler  
> name:BDSKDocDelItemNotification object:aDocument];
> +        [nc addObserver:self selector:handler  
> name:NSApplicationWillTerminateNotification object:aDocument];
>
>          flags.isIndexing = 0;
>          flags.shouldKeepRunning = 1;
> @@ -129,11 +166,8 @@
>
>          // block until the NSMachPort is set up to receive messages
>          [setupLock lockWhenCondition:INDEX_STARTUP_COMPLETE];
> -        [setupLock unlock];
> -
> -        // done with this lock, so get rid of it now
> -        [setupLock release];
> -        setupLock = nil;
> +        [setupLock unlockWithCondition:INDEX_THREAD_WORKING];
> +
>      }
>
>      return self;
> @@ -141,23 +175,31 @@
>
>  - (void)dealloc
>  {
> +    [indexCacheURL release];
>      [notificationPort release];
>      [notificationQueue release];
>      [itemInfos release];
>      [signatures release];
>      if(index) CFRelease(index);
>      if(indexData) CFRelease(indexData);
> +    [setupLock release];
>      [super dealloc];
>  }
>
> -// cancel is usually sent from the main thread
> +// cancel is always sent from the main thread
>  - (void)cancel
>  {
> +    NSParameterAssert([NSThread inMainThread]);
>      [[NSNotificationCenter defaultCenter] removeObserver:self];
>      OSAtomicCompareAndSwap32(flags.shouldKeepRunning, 0, (int32_t  
> *)&flags.shouldKeepRunning);
>
>      // wake the thread up so the runloop will exit
>      [notificationPort sendBeforeDate:[NSDate date] components:nil  
> from:nil reserved:0];
> +
> +    // wait until the thread exits, so we have exclusive access to  
> the ivars
> +    [setupLock lockWhenCondition:INDEX_THREAD_DONE];
> +    [self writeIndexToDisk];
> +    [setupLock unlock];
>  }
>
>  - (SKIndexRef)index
> @@ -182,21 +224,12 @@
>  - (NSDictionary *)itemInfoForURL:(NSURL *)theURL
>  {
>      NSDictionary *itemInfo = nil;
> -    @synchronized(itemInfos) {
> +    @synchronized(self) {
>          itemInfo = [[itemInfos objectForKey:theURL] retain];
>      }
>      return [itemInfo autorelease];
>  }
>
> -- (NSData *)signatureForURL:(NSURL *)theURL
> -{
> -    NSData *signature = nil;
> -    @synchronized(signature) {
> -        signature = [[signatures objectForKey:theURL] retain];
> -    }
> -    return [signature autorelease];
> -}
> -
>  - (double)progressValue
>  {
>      double theValue;
> @@ -206,20 +239,10 @@
>      return theValue;
>  }
>
> -- (BOOL)closeIndexAndCacheToURL:(NSURL *)cacheURL
> +- (void)setDocumentURL:(NSURL *)aURL
>  {
> -    // I'm not sure if this is all safe
> -    [self cancel];
> -    while ([self isIndexing]);
> -    if (index) {
> -        SKIndexClose(index);
> -        index = NULL;
> -    }
> -    NSDictionary *cacheDict = nil;
> -    @synchronized(signatures) {
> -        cacheDict = [NSDictionary dictionaryWithObjectsAndKeys: 
> [[(NSData *)indexData copy] autorelease], @"indexData",  
> [[signatures copy] autorelease], @"signatures", nil];
> -    }
> -    return [NSKeyedArchiver archiveRootObject:cacheDict toFile: 
> [cacheURL path]];
> +    [documentURL autorelease];
> +    documentURL = [aURL copy];
>  }
>
>  @end
> @@ -229,7 +252,7 @@
>      SKIndexDocumentIteratorRef iterator =  
> SKIndexDocumentIteratorCreate (anIndex, inParentDocument);
>      SKDocumentRef skDocument;
>      CFURLRef aURL;
> -    Boolean isLeaf = true;
> +    bool isLeaf = true;
>
>      while (skDocument = SKIndexDocumentIteratorCopyNext(iterator)) {
>          isLeaf = false;
> @@ -246,6 +269,14 @@
>
>  @implementation BDSKFileSearchIndex (Private)
>
> +static inline NSData *sha1SignatureForURL(NSURL *aURL) {
> +    // using the mapped data options will cause a crash in the  
> sha1Signature method
> +    NSData *data = [[NSData alloc] initWithContentsOfURL:aURL];
> +    NSData *sha1Signature = [data sha1Signature];
> +    [data release];
> +    return sha1Signature;
> +}
> +
>  - (NSArray *)itemsToIndex:(NSArray *)items
>  {
>      [items retain];
> @@ -262,9 +293,14 @@
>
>      NSEnumerator *itemEnum = [items objectEnumerator];
>      id anItem = nil;
> +    NSMutableDictionary *previouslyIndexedInfos =  
> [NSMutableDictionary dictionary];
> +    double numberIndexed = 0;
>      double totalObjectCount = [items count];
> -    double numberIndexed = 0;
>
> +    // see comment later; may need tuning here since this is much  
> faster, or else use a message queue instead of passing  
> waitUntilDone:YES
> +    const int32_t flushInterval = 20;
> +    int32_t countSinceLastFlush = flushInterval;
> +
>      // update the itemInfos with the items, find items to add and  
> URLs to remove
>      OSMemoryBarrier();
>      while(flags.shouldKeepRunning == 1 && (anItem = [itemEnum  
> nextObject])) {
> @@ -275,15 +311,11 @@
>
>          while (url = [urlEnum nextObject]) {
>              if ([indexedURLs containsObject:url]) {
> -                if ([[self signatureForURL:url]  
> isEqual:sha1SignatureForURL(url)]) {
> +                if ([[signatures objectForKey:url]  
> isEqual:sha1SignatureForURL(url)]) {
>                      [URLsToRemove removeObject:url];
> -                    @synchronized(itemInfos) {
> -                        [itemInfos setObject:anItem forKey:url];
> -                    }
> +                    [previouslyIndexedInfos setObject:anItem  
> forKey:url];
>                  } else {
> -                    @synchronized(signatures) {
> -                        [signatures removeObjectForKey:url];
> -                    }
> +                    [signatures removeObjectForKey:url];
>                      needsIndexing = YES;
>                  }
>              } else {
> @@ -291,20 +323,26 @@
>              }
>          }
>
> +        // ??? is it worth updating progress here since it runs so  
> fast?  we'd also need to send delegate messages periodically
> +
>          if (needsIndexing) {
>              [itemsToAdd addObject:anItem];
>          } else {
>              numberIndexed++;
>              @synchronized(self) {
>                  progressValue = (numberIndexed / totalObjectCount)  
> * 100;
> +                [itemInfos  
> addEntriesFromDictionary:previouslyIndexedInfos];
> +                [previouslyIndexedInfos removeAllObjects];
>              }
> +            if (countSinceLastFlush-- == 0) {
> +                [delegate performSelectorOnMainThread:@selector 
> (searchIndexDidUpdate:) withObject:self waitUntilDone:YES];
> +                countSinceLastFlush = flushInterval;
> +            }
>          }
> +
>          OSMemoryBarrier();
>      }
> -
> -    OSMemoryBarrier();
> -    if (flags.shouldKeepRunning == 1)
> -        [delegate performSelectorOnMainThread:@selector 
> (searchIndexDidUpdate:) withObject:self waitUntilDone:NO];
> +
>
>      // remove URLs we could not find in the database
>      OSMemoryBarrier();
> @@ -312,27 +350,23 @@
>          NSEnumerator *urlEnum = [URLsToRemove objectEnumerator];
>          NSURL *url;
>          SKDocumentRef skDocument;
> -        volatile Boolean success;
>
>          // loop through the array of URLs, create a new  
> SKDocumentRef, and try to remove it
>          while (url = [urlEnum nextObject]) {
>
>              skDocument = SKDocumentCreateWithURL((CFURLRef)url);
> -            OBPOSTCONDITION(skDocument);
> -            if(!skDocument) continue;
> -
> -            success = SKIndexRemoveDocument(index, skDocument);
> -            OBPOSTCONDITION(success);
> -
> -            CFRelease(skDocument);
> +            if (skDocument) {
> +                SKIndexRemoveDocument(index, skDocument);
> +                CFRelease(skDocument);
> +            }
>          }
>      }
>      [URLsToRemove release];
> -
> +    [items release];
> +
>      OSMemoryBarrier();
>      if (flags.shouldKeepRunning == 1)
>          [delegate performSelectorOnMainThread:@selector 
> (searchIndexDidUpdate:) withObject:self waitUntilDone:NO];
> -    [items release];
>
>      return itemsToAdd;
>  }
> @@ -343,31 +377,35 @@
>
>      OBPRECONDITION(items);
>
> +    // normally set in the indexFilesForItem: method, but we need  
> to avoid returning NO for isIndexing here as well
> +    OSAtomicCompareAndSwap32Barrier(0, 1, (int32_t *) 
> &flags.isIndexing);
> +
> +    double totalObjectCount = [items count];
>      items = [self itemsToIndex:items];
> +    double numberIndexed = totalObjectCount - [items count];
>
>      [items retain];
>
>      // add items that were not yet indexed
>      OSMemoryBarrier();
>      if (flags.shouldKeepRunning == 1 && [items count]) {
> -        [self indexFilesForItems:items];
> +        [self indexFilesForItems:items  
> numberPreviouslyIndexed:numberIndexed totalCount:totalObjectCount];
>      }
>
>      [items release];
> -
> +    OSAtomicCompareAndSwap32Barrier(1, 0, (int32_t *) 
> &flags.isIndexing);
> +
>      OSMemoryBarrier();
>      if (flags.shouldKeepRunning == 1)
>          [delegate performSelectorOnMainThread:@selector 
> (searchIndexDidFinishInitialIndexing:) withObject:self  
> waitUntilDone:NO];
>  }
>
> -- (void)indexFilesForItems:(NSArray *)items
> +- (void)indexFilesForItems:(NSArray *)items  
> numberPreviouslyIndexed:(double)numberIndexed totalCount:(double) 
> totalObjectCount
>  {
>      NSAssert2([[NSThread currentThread]  
> isEqual:notificationThread], @"-[%@ [EMAIL PROTECTED] must be called from the 
>  
> worker thread!", [self class], NSStringFromSelector(_cmd));
>
>      NSEnumerator *enumerator = [items objectEnumerator];
>      id anObject = nil;
> -    double totalObjectCount = [items count];
> -    double numberIndexed = 0;
>
>      // This threshold is sort of arbitrary; for small batches,  
> frequent updates are better if the delegate has a progress  
> indicator, but for large batches (initial indexing), it can kill  
> performance to be continually flushing and searching while indexing.
>      const int32_t flushInterval = [items count] > 20 ? 5 : 1;
> @@ -428,15 +466,13 @@
>
>          // SKIndexSetProperties is more generally useful, but is  
> really slow when creating the index
>          // SKIndexRenameDocument changes the URL, so it's not useful
> -        @synchronized(itemInfos) {
> +        @synchronized(self) {
>              [itemInfos setObject:anItem forKey:url];
>          }
> -        @synchronized(signatures) {
> -            if (signature)
> -                [signatures setObject:signature forKey:url];
> -            else
> -                [signatures removeObjectForKey:url];
> -        }
> +        if (signature)
> +            [signatures setObject:signature forKey:url];
> +        else
> +            [signatures removeObjectForKey:url];
>
>          success = SKIndexAddDocument(index, skDocument, NULL, TRUE);
>          OBPOSTCONDITION(success);
> @@ -449,6 +485,22 @@
>      // the caller is responsible for updating the delegate, so we  
> can throttle initial indexing
>  }
>
> +- (void)writeIndexToDisk
> +{
> +    NSParameterAssert([NSThread inMainThread]);
> +    NSParameterAssert([setupLock condition] == INDEX_THREAD_DONE);
> +    if (index && [[NSUserDefaults standardUserDefaults]  
> boolForKey:@"BDSKShouldCacheFileSearchIndexKey"]) {
> +        // flush all pending updates and compact the index as  
> needed before writing
> +        SKIndexCompact(index);
> +        CFRelease(index);
> +        index = NULL;
> +
> +        NSDictionary *cacheDict = nil;
> +        cacheDict = [NSDictionary dictionaryWithObjectsAndKeys: 
> (NSData *)indexData, @"indexData", signatures, @"signatures",  
> documentURL, @"documentURL", nil];
> +        [NSKeyedArchiver archiveRootObject:cacheDict toFile: 
> [indexCacheURL path]];
> +    }
> +}
> +
>  - (void)runIndexThreadForItems:(NSArray *)items
>  {
>      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
> @@ -465,6 +517,8 @@
>      notificationQueue = [[BDSKThreadSafeMutableArray alloc]  
> initWithCapacity:5];
>      [setupLock unlockWithCondition:INDEX_STARTUP_COMPLETE];
>
> +    [setupLock lockWhenCondition:INDEX_THREAD_WORKING];
> +
>      // an exception here can probably be ignored safely
>      @try{
>          [self buildIndexForItems:items];
> @@ -490,6 +544,12 @@
>      }
>      @catch(id localException){
>          NSLog(@"Exception %@ raised in search index; exiting  
> thread run loop.", localException);
> +
> +        // clean these up to make sure we have no chance of saving  
> it to disk
> +        if (index) CFRelease(index);
> +        index = NULL;
> +        if (indexData) CFRelease(indexData);
> +        indexData = NULL;
>          @throw;
>      }
>      @finally{
> @@ -498,15 +558,21 @@
>          [notificationThread release];
>          notificationThread = nil;
>          [notificationPort invalidate];
> +        [setupLock unlockWithCondition:INDEX_THREAD_DONE];
>      }
>  }
>
>  - (void)processNotification:(NSNotification *)note
>  {
>      OBASSERT([NSThread inMainThread]);
> -    // Forward the notification to the correct thread
> -    [notificationQueue addObject:note];
> -    [notificationPort sendBeforeDate:[NSDate date] components:nil  
> from:nil reserved:0];
> +    if ([[note name]  
> isEqualToString:NSApplicationWillTerminateNotification]) {
> +        [self cancel];
> +
> +    } else {
> +        // Forward the notification to the correct thread
> +        [notificationQueue addObject:note];
> +        [notificationPort sendBeforeDate:[NSDate date]  
> components:nil from:nil reserved:0];
> +    }
>  }
>
>  - (void)handleDocAddItemNotification:(NSNotification *)note
> @@ -517,7 +583,7 @@
>      OBPRECONDITION(searchIndexInfo);
>
>      // this will update the delegate when all is complete
> -    [self indexFilesForItems:searchIndexInfo];
> +    [self indexFilesForItems:searchIndexInfo  
> numberPreviouslyIndexed:0 totalCount:1];
>  }
>
>  - (void)handleDocDelItemNotification:(NSNotification *)note
> @@ -549,12 +615,10 @@
>                       
>                       url = [urls objectAtIndex:idx];
>
> -            @synchronized(itemInfos) {
> +            @synchronized(self) {
>                  [itemInfos removeObjectForKey:url];
>              }
> -            @synchronized(signatures) {
> -                [signatures removeObjectForKey:url];
> -            }
> +            [signatures removeObjectForKey:url];
>                       
>                       skDocument = SKDocumentCreateWithURL((CFURLRef)url);
>                       OBPOSTCONDITION(skDocument);
>
>
> This was sent by the SourceForge.net collaborative development  
> platform, the world's largest Open Source development site.
>
> ---------------------------------------------------------------------- 
> ---
> This SF.net email is sponsored by: Microsoft
> Defy all challenges. Microsoft(R) Visual Studio 2008.
> http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
> _______________________________________________
> Bibdesk-commit mailing list
> [EMAIL PROTECTED]
> https://lists.sourceforge.net/lists/listinfo/bibdesk-commit


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Bibdesk-develop mailing list
Bibdesk-develop@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bibdesk-develop

Reply via email to