Revision: 28510
http://sourceforge.net/p/bibdesk/svn/28510
Author: hofman
Date: 2024-01-02 00:29:30 +0000 (Tue, 02 Jan 2024)
Log Message:
-----------
use NSHashTable with custom pointer functions for BibItem equality and
equivalence rather than bridges CFSet
Modified Paths:
--------------
trunk/bibdesk/BDSKSharingServer.m
trunk/bibdesk/BibDocument_Actions.m
trunk/bibdesk/BibDocument_Groups.m
trunk/bibdesk/NSPointerFunctions_BDSKExtensions.h
trunk/bibdesk/NSPointerFunctions_BDSKExtensions.m
Modified: trunk/bibdesk/BDSKSharingServer.m
===================================================================
--- trunk/bibdesk/BDSKSharingServer.m 2024-01-01 23:50:39 UTC (rev 28509)
+++ trunk/bibdesk/BDSKSharingServer.m 2024-01-02 00:29:30 UTC (rev 28510)
@@ -50,6 +50,7 @@
#import "BDSKPublicationsArray.h"
#import "BDSKMacroResolver.h"
#import "NSObject_BDSKExtensions.h"
+#import "NSPointerFunctions_BDSKExtensions.h"
#include <sys/socket.h>
#include <netinet/in.h>
@@ -840,10 +841,11 @@
__block NSDictionary *pubsAndMacros = nil;
dispatch_sync(dispatch_get_main_queue(), ^{
- NSMutableSet *allPubs = (NSMutableSet
*)CFSetCreateMutable(CFAllocatorGetDefault(), 0,
&kBDSKBibItemEqualitySetCallBacks);
+ NSHashTable *allPubs = [[NSHashTable alloc]
initWithPointerFunctions:[NSPointerFunctions itemEqualityPointerFunctions]
capacity:0];
NSMutableDictionary *allMacros = [[NSMutableDictionary alloc] init];
for (BibDocument *doc in [NSApp orderedDocuments]) {
- [allPubs addObjectsFromArray:[doc publications]];
+ for (BibItem *pub in [doc publications])
+ [allPubs addObject:pub];
NSMapTable *macroDefs = [[doc macroResolver] macroDefinitions];
for (NSString *key in macroDefs)
[allMacros setObject:[macroDefs objectForKey:key] forKey:key];
Modified: trunk/bibdesk/BibDocument_Actions.m
===================================================================
--- trunk/bibdesk/BibDocument_Actions.m 2024-01-01 23:50:39 UTC (rev 28509)
+++ trunk/bibdesk/BibDocument_Actions.m 2024-01-02 00:29:30 UTC (rev 28510)
@@ -95,6 +95,7 @@
#import "BDSKColorLabelWell.h"
#import "BDSKMergeController.h"
#import "BDSKFindController.h"
+#import "NSPointerFunctions_BDSKExtensions.h"
#define BDSKLyXPipePathKey @"BDSKLyXPipePath"
@@ -1712,20 +1713,22 @@
NSMutableArray *duplicatePubs = nil;
NSZone *zone = NSDefaultMallocZone();
CFIndex countOfItems = [publications count];
- BibItem **pubs = (BibItem **)NSZoneMalloc(zone, sizeof(BibItem *) *
countOfItems);
- CFSetCallBacks callBacks = kBDSKBibItemEqualitySetCallBacks;
-
- [publications getObjects:pubs range:NSMakeRange(0, countOfItems)];
+ NSPointerFunctions *pointerFunctions = nil;
+ NSArray *pubs = nil;
if ([self hasGroupTypeSelected:BDSKExternalGroupType]) {
duplicatePubs = [[NSMutableArray alloc]
initWithArray:groupedPublications];
- callBacks = kBDSKBibItemEquivalenceSetCallBacks;
+ pointerFunctions = [NSPointerFunctions
itemEquivalencePointerFunctions];
+ pubs = [publications copy];
} else {
duplicatePubs = [[NSMutableArray alloc] initWithArray:publications];
+ pointerFunctions = [NSPointerFunctions itemEqualityPointerFunctions];
// Tests equality based on standard fields (high probability that
these will be duplicates)
countOfItems = [duplicatePubs count];
- NSSet *uniquePubs = (NSSet *)CFSetCreate(CFAllocatorGetDefault(),
(const void **)pubs, countOfItems, &callBacks);
+ NSHashTable *uniquePubs = [[NSHashTable alloc]
initWithPointerFunctions:pointerFunctions capacity:countOfItems];
+ for (BibItem *pub in publications)
+ [uniquePubs addObject:pub];
// remove all unique ones based on pointer equality
for (BibItem *pub in uniquePubs)
[duplicatePubs removeObjectIdenticalTo:pub];
@@ -1732,14 +1735,15 @@
[uniquePubs release];
// original buffer should be large enough, since we've only removed
items from pubsToRemove
- countOfItems = [duplicatePubs count];
- [duplicatePubs getObjects:pubs range:NSMakeRange(0, countOfItems)];
+ pubs = [duplicatePubs copy];
[duplicatePubs setArray:publications];
}
if (allCandidates) {
- NSSet *removeSet = (NSSet *)CFSetCreate(CFAllocatorGetDefault(),
(const void **)pubs, countOfItems, &callBacks);
-
+ NSHashTable *removeSet = [[NSHashTable alloc]
initWithPointerFunctions:pointerFunctions capacity:countOfItems];
+ for (BibItem *pub in pubs)
+ [removeSet addObject:pub];
+
CFIndex idx = [duplicatePubs count];
while(idx--){
@@ -1748,13 +1752,12 @@
}
[removeSet release];
- [self selectPublications:duplicatePubs];
+ [self selectPublications:duplicatePubs];
} else {
- [duplicatePubs release];
- duplicatePubs = [[NSMutableArray alloc] initWithObjects:pubs
count:countOfItems];
+ [duplicatePubs setArray:pubs];
[self selectPublications:duplicatePubs];
}
- NSZoneFree(zone, pubs);
+ [pubs release];
[duplicatePubs release];
if(countOfItems)
Modified: trunk/bibdesk/BibDocument_Groups.m
===================================================================
--- trunk/bibdesk/BibDocument_Groups.m 2024-01-01 23:50:39 UTC (rev 28509)
+++ trunk/bibdesk/BibDocument_Groups.m 2024-01-02 00:29:30 UTC (rev 28510)
@@ -1353,11 +1353,9 @@
- (NSArray *)mergeInPublications:(NSArray *)items{
// first construct a set of current items to compare based on BibItem
equality callbacks
- CFIndex countOfItems = [publications count];
- BibItem **pubs = (BibItem **)NSZoneMalloc(NULL, sizeof(BibItem *) *
countOfItems);
- [publications getObjects:pubs range:NSMakeRange(0, countOfItems)];
- NSSet *currentPubs = [(NSSet *)CFSetCreate(CFAllocatorGetDefault(), (const
void **)pubs, countOfItems, &kBDSKBibItemEquivalenceSetCallBacks) autorelease];
- NSZoneFree(NULL, pubs);
+ NSHashTable *currentPubs = [[NSHashTable alloc]
initWithPointerFunctions:[NSPointerFunctions itemEquivalencePointerFunctions]
capacity:[publications count]];
+ for (BibItem *pub in publications)
+ [currentPubs addObject:pub];
NSMutableArray *newPubs = [NSMutableArray arrayWithCapacity:[items count]];
@@ -1370,6 +1368,8 @@
}
}
+ [currentPubs release];
+
if ([newPubs count] == 0)
return @[];
@@ -1620,11 +1620,9 @@
#pragma mark Importing
- (void)setImported:(BOOL)flag forPublications:(NSArray *)pubs
inGroup:(BDSKExternalGroup *)aGroup{
- CFIndex countOfItems = [pubs count];
- BibItem **items = (BibItem **)NSZoneMalloc(NULL, sizeof(BibItem *) *
countOfItems);
- [pubs getObjects:items range:NSMakeRange(0, countOfItems)];
- NSSet *pubSet = (NSSet *)CFSetCreate(CFAllocatorGetDefault(), (const void
**)items, countOfItems, &kBDSKBibItemEquivalenceSetCallBacks);
- NSZoneFree(NULL, items);
+ NSHashTable *pubSet = [[NSHashTable alloc]
initWithPointerFunctions:[NSPointerFunctions itemEquivalencePointerFunctions]
capacity:[pubs count]];
+ for (BibItem *pub in pubs)
+ [pubSet addObject:pub];
NSArray *groupsToTest = aGroup ? @[aGroup] : [[groups externalParent]
children];
Modified: trunk/bibdesk/NSPointerFunctions_BDSKExtensions.h
===================================================================
--- trunk/bibdesk/NSPointerFunctions_BDSKExtensions.h 2024-01-01 23:50:39 UTC
(rev 28509)
+++ trunk/bibdesk/NSPointerFunctions_BDSKExtensions.h 2024-01-02 00:29:30 UTC
(rev 28510)
@@ -43,5 +43,7 @@
+ (NSPointerFunctions *)caseInsensitiveStringPointerFunctions;
+ (NSPointerFunctions *)fuzzyAuthorPointerFunctions;
++ (NSPointerFunctions *)itemEqualityPointerFunctions;
++ (NSPointerFunctions *)itemEquivalencePointerFunctions;
@end
Modified: trunk/bibdesk/NSPointerFunctions_BDSKExtensions.m
===================================================================
--- trunk/bibdesk/NSPointerFunctions_BDSKExtensions.m 2024-01-01 23:50:39 UTC
(rev 28509)
+++ trunk/bibdesk/NSPointerFunctions_BDSKExtensions.m 2024-01-02 00:29:30 UTC
(rev 28510)
@@ -38,6 +38,9 @@
#import "NSPointerFunctions_BDSKExtensions.h"
#import "BibAuthor.h"
+#import "BibItem.h"
+#import "BDSKTypeManager.h"
+#import "CFString_BDSKExtensions.h"
static BOOL caseInsensitiveStringEqual(const void *item1, const void *item2,
NSUInteger (*size)(const void *item)) {
return CFStringCompare(item1, item2, kCFCompareCaseInsensitive |
kCFCompareNonliteral) == kCFCompareEqualTo;
@@ -81,6 +84,48 @@
return [(BibAuthor *)value1 fuzzyEqual:(BibAuthor *)value2];
}
+static NSUInteger BibItemEqualityHash(const void *item, NSUInteger
(*size)(const void *item))
+{
+ BDSKASSERT([(id)item isKindOfClass:[BibItem class]]);
+ return BDCaseInsensitiveStringHash([(BibItem *)item citeKey]);
+}
+
+static BOOL BibItemEqual(const void *value1, const void *value2, NSUInteger
(*size)(const void *item))
+{
+ BDSKASSERT([(id)value1 isKindOfClass:[BibItem class]] && [(id)value2
isKindOfClass:[BibItem class]]);
+ return ([(BibItem *)value1 isEqualToItem:(BibItem *)value2]);
+}
+
+static NSUInteger BibItemEquivalenceHash(const void *item, NSUInteger
(*size)(const void *item))
+{
+ BDSKASSERT([(id)item isKindOfClass:[BibItem class]]);
+
+ NSString *type = [(BibItem *)item pubType] ?: @"";
+ CFHashCode hash = BDCaseInsensitiveStringHash(type);
+ NSUInteger prime = 31;
+ NSUInteger factor = 1;
+
+ // hash only the standard fields; are these all we should compare?
+ BDSKTypeManager *btm = [BDSKTypeManager sharedManager];
+ NSMutableArray *keys = [[NSMutableArray alloc] initWithCapacity:20];
+ [keys addObjectsFromArray:[btm requiredFieldsForType:type]];
+ [keys addObjectsFromArray:[btm optionalFieldsForType:type]];
+ [keys removeObject:BDSKLocalUrlString];
+ for (NSString *key in keys) {
+ factor *= prime;
+ hash += factor * [[(BibItem *)item stringValueOfField:key inherit:NO]
?: @"" hash];
+ }
+ [keys release];
+
+ return hash;
+}
+
+static BOOL BibItemEquivalent(const void *value1, const void *value2,
NSUInteger (*size)(const void *item))
+{
+ BDSKASSERT([(id)value1 isKindOfClass:[BibItem class]] && [(id)value2
isKindOfClass:[BibItem class]]);
+ return ([(BibItem *)value1 isEquivalentToItem:(BibItem *)value2]);
+}
+
@implementation NSPointerFunctions (BDSKExtensions)
+ (NSPointerFunctions *)caseInsensitiveStringPointerFunctions {
@@ -97,4 +142,18 @@
return pointerFunctions;
}
++ (NSPointerFunctions *)itemEqualityPointerFunctions {
+ NSPointerFunctions *pointerFunctions = [self
pointerFunctionsWithOptions:NSPointerFunctionsWeakMemory |
NSPointerFunctionsObjectPersonality];;
+ [pointerFunctions setIsEqualFunction:&BibItemEqual];
+ [pointerFunctions setHashFunction:&BibItemEqualityHash];
+ return pointerFunctions;
+}
+
++ (NSPointerFunctions *)itemEquivalencePointerFunctions {
+ NSPointerFunctions *pointerFunctions = [self
pointerFunctionsWithOptions:NSPointerFunctionsWeakMemory |
NSPointerFunctionsObjectPersonality];;
+ [pointerFunctions setIsEqualFunction:&BibItemEquivalent];
+ [pointerFunctions setHashFunction:&BibItemEquivalenceHash];
+ return pointerFunctions;
+}
+
@end
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
_______________________________________________
Bibdesk-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bibdesk-commit