Skip to content

Commit

Permalink
Merge pull request #8 from HendrikNoeller/master
Browse files Browse the repository at this point in the history
Fix chuzzling large arrays
  • Loading branch information
mxcl authored Dec 16, 2024
2 parents 6aeab50 + 9cef585 commit c3c7ed2
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 16 deletions.
32 changes: 16 additions & 16 deletions Sources/ChuzzleKit.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,19 @@ - (id)chuzzle {
if (self.count == 0) {
return nil;
}
id objs[self.count];
id keys[self.count];
NSUInteger x = 0;
NSMutableArray* objs = [NSMutableArray arrayWithCapacity:self.count];
NSMutableArray* keys = [NSMutableArray arrayWithCapacity:self.count];
for (id key in self) {
id obj = self[key];
if ([obj respondsToSelector:@selector(chuzzle)])
obj = [obj chuzzle];
if ([obj respondsToSelector:@selector(chuzzle)]) {
obj = [obj chuzzle];
}
if (obj) {
objs[x] = obj;
keys[x] = key;
x += 1;
[objs addObject:obj];
[keys addObject:key];
}
}
return x == 0 ? nil : [NSDictionary dictionaryWithObjects:objs forKeys:keys count:x];
return (objs.count == 0) ? nil : [NSDictionary dictionaryWithObjects:objs forKeys:keys];
}

@end
Expand All @@ -42,15 +41,16 @@ - (instancetype)chuzzle {
if (self.count == 0) {
return nil;
}
id objs[self.count];
NSUInteger x = 0;
NSMutableArray* result = [NSMutableArray arrayWithCapacity:self.count];
for (__strong id obj in self) {
if ([obj respondsToSelector:@selector(chuzzle)])
obj = [obj chuzzle];
if (obj)
objs[x++] = obj;
if ([obj respondsToSelector:@selector(chuzzle)]) {
obj = [obj chuzzle];
}
if (obj) {
[result addObject:obj];
}
}
return x == 0 ? nil : [NSArray arrayWithObjects:objs count:x];
return result.count == 0 ? nil : [NSArray arrayWithArray:result];
}

@end
Expand Down
14 changes: 14 additions & 0 deletions Tests/ChuzzleTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,19 @@ - (void)test_nsobject {
id o = [NSObject new];
XCTAssertEqual(o, [o chuzzle]);
}
- (void)test_giant_array {
// using a very large number of objectcs to illustrate the problem
// and make the test trip on powerful desktop machines, but issues
// would obviously manifest sooner on mobile devices with less memory
NSUInteger size = 50000000;
NSMutableArray* a = [NSMutableArray arrayWithCapacity:size];
for (int i = 0; i < size; i++) {
[a addObject:i % 2 ? @(i) : NSNull.null];
}
a = [NSArray arrayWithArray:a];
NSArray* b;
XCTAssertNoThrow(b = a.chuzzle);
XCTAssertEqual(b.count, a.count / 2);
}

@end

0 comments on commit c3c7ed2

Please sign in to comment.