Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A very fast sortUsingDescriptors: #1560

Merged
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
175 changes: 140 additions & 35 deletions Foundation/CPArray/CPMutableArray.j
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,15 @@

- (void)sortUsingDescriptors:(CPArray)descriptors
{
[self sortUsingFunction:compareObjectsUsingDescriptors context:descriptors];
var i = [descriptors count],
jsDescriptors = [];
// Revert the order of the descriptors
while (i--)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and everywhere else, please separate all control structures (and their bracketed code blocks) from surrounding code with a blank line.

{
var d = [descriptors objectAtIndex:i];
[jsDescriptors addObject:{ "k": [d key], "a": [d ascending]}];
}
sortArrayUsingJSDescriptors(self, jsDescriptors);
}

/*!
Expand All @@ -343,14 +351,46 @@
@param aContext an object that will be passed to \c aFunction with comparison
*/
- (void)sortUsingFunction:(Function)aFunction context:(id)aContext
{
sortArrayUsingFunction(self, aFunction, aContext);
}

/*!
Sorts the receiver array using an Objective-J method as a comparator.
@param aSelector the selector for the method to call for comparison
*/
- (void)sortUsingSelector:(SEL)aSelector
{
sortArrayUsingFunction(self, selectorCompare, aSelector);
}

@end

@implementation CPArray (CPMutableCopying)

- (id)mutableCopy
{
var r = [CPMutableArray new];
[r addObjectsFromArray:self];
return r;
}

@end

var selectorCompare = function selectorCompare(object1, object2, selector)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eliminate the name after function, it's redundant, ignored by Javascript, and capp_lint will complain.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just copying what was done before but I can fix that if you want to.....

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix it, we are being a little stricter about formatting now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure!

{
return [object1 performSelector:selector withObject:object2];
};

var sortArrayUsingFunction = function sortArrayUsingFunction(array, aFunction, aContext)
{
var h,
i,
j,
k,
l,
m,
n = [self count],
n = array.length,
o;

var A,
Expand All @@ -365,56 +405,29 @@
l = 0;

for (i = 0, j = l; j <= m; i++, j++)
B[i] = self[j];
B[i] = array[j];

for (i = 0, k = l; k < j && j <= m + h; k++)
{
A = self[j];
A = array[j];
o = aFunction(A, B[i], aContext);
if (o >= 0)
self[k] = B[i++];
array[k] = B[i++];
else
{
self[k] = A;
array[k] = A;
j++;
}
}

while (k < j)
self[k++] = B[i++];
array[k++] = B[i++];
}
}
}

/*!
Sorts the receiver array using an Objective-J method as a comparator.
@param aSelector the selector for the method to call for comparison
*/
- (void)sortUsingSelector:(SEL)aSelector
{
[self sortUsingFunction:selectorCompare context:aSelector];
}

@end

@implementation CPArray (CPMutableCopying)

- (id)mutableCopy
{
var r = [CPMutableArray new];
[r addObjectsFromArray:self];
return r;
}

@end

var selectorCompare = function selectorCompare(object1, object2, selector)
{
return [object1 performSelector:selector withObject:object2];
};

// sort using sort descriptors
var compareObjectsUsingDescriptors= function compareObjectsUsingDescriptors(lhs, rhs, descriptors)
var compareObjectsUsingDescriptors = function compareObjectsUsingDescriptors(lhs, rhs, descriptors)
{
var result = CPOrderedSame,
i = 0,
Expand All @@ -425,3 +438,95 @@ var compareObjectsUsingDescriptors= function compareObjectsUsingDescriptors(lhs,

return result;
};

// Observe that the sort descriptors has the reversed order by the caller
var sortArrayUsingJSDescriptors = function sortArrayUsingJSDescriptors(a, d)
{
var h,
i,
j,
k,
l,
m,
n = a.length,
dl = d.length - 1,
o,
c = {};

var A,
B = [],
C1,
C2,
cn,
aUID,
bUID,
key;

if (dl < 0)
return;
for (h = 1; h < n; h += h)
{
for (m = n - 1 - h; m >= 0; m -= h + h)
{
l = m - h + 1;
if (l < 0)
l = 0;

for (i = 0, j = l; j <= m; i++, j++)
B[i] = a[j];

for (i = 0, k = l; k < j && j <= m + h; k++)
{
A = a[j];
aUID = A._UID;
if (!aUID)
aUID = [A UID];
C1 = c[aUID];
if (!C1)
{
C1 = {};
cn = dl;
do
{
key = d[cn].k;
C1[key] = [A valueForKey:key];
} while (cn--)
c[aUID] = C1;
}
bUID = B[i]._UID;
if (!bUID)
bUID = [B[i] UID];
C2 = c[bUID];
if (!C2)
{
C2 = {};
cn = dl;
do
{
key = d[cn].k;
C2[key] = [B[i] valueForKey:key];
} while (cn--)
c[bUID] = C2;
}
cn = dl;
do
{
key = d[cn].k;
o = [C1[key] compare:C2[key]];
if (o && !d[cn].a)
o = -o;
} while (cn-- && o == CPOrderedSame)
if (o >= 0)
a[k] = B[i++];
else
{
a[k] = A;
j++;
}
}

while (k < j)
a[k++] = B[i++];
}
}
}