mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-20 20:26:42 +00:00
hash tidyups and rewrite of array sorting for better performance.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@23967 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
c1d009c3c1
commit
595be905a3
11 changed files with 180 additions and 173 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
||||||
|
2006-10-26 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
* Source/NSPropertyList.m: use declaration of GSArray from GSPrivate.h
|
||||||
|
* Source/GSArray.m: ditto
|
||||||
|
* Source/NSArray.m: ditto
|
||||||
|
* Source/NSSerializer.m ditto
|
||||||
|
* Source/NSConcreteNumberTemplate.m: Use private function to get hash.
|
||||||
|
* Source/NSConcreteNumber.m: ditto
|
||||||
|
* Source/NSNumber.m: ditto
|
||||||
|
* Source/GSPrivate.h: Add hash functions.
|
||||||
|
* Headers/Foundation/NSSortDescriptor.h: Add a little documentation.
|
||||||
|
* Source/NSSortDescriptor.m: Implement better hash/isEqual as
|
||||||
|
suggested by David. Complete rewrite of sorting to avoid lots of
|
||||||
|
heap memory operations ... should be much much faster.
|
||||||
|
|
||||||
2006-10-25 Richard Frith-Macdonald <rfm@gnu.org>
|
2006-10-25 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* configure.ac: Define HAVE_VISIBILITY_ATTRIBUTE if gcc's visibility
|
* configure.ac: Define HAVE_VISIBILITY_ATTRIBUTE if gcc's visibility
|
||||||
|
|
|
@ -63,6 +63,17 @@ extern "C" {
|
||||||
|
|
||||||
@interface NSMutableArray (NSSortDescriptorSorting)
|
@interface NSMutableArray (NSSortDescriptorSorting)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method works like this: first, it sorts the entire
|
||||||
|
* contents of the array using the first sort descriptor. Then,
|
||||||
|
* after each sort-run, it looks whether there are sort
|
||||||
|
* descriptors left to process, and if yes, looks at the partially
|
||||||
|
* sorted array, finds all portions in it which are equal
|
||||||
|
* (evaluate to NSOrderedSame) and applies the following
|
||||||
|
* descriptor onto them. It repeats this either until all
|
||||||
|
* descriptors have been applied or there are no more equal
|
||||||
|
* portions (equality ranges) left in the array.
|
||||||
|
*/
|
||||||
- (void) sortUsingDescriptors: (NSArray *)sortDescriptors;
|
- (void) sortUsingDescriptors: (NSArray *)sortDescriptors;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -36,6 +36,8 @@
|
||||||
// For private method _decodeArrayOfObjectsForKey:
|
// For private method _decodeArrayOfObjectsForKey:
|
||||||
#include "Foundation/NSKeyedArchiver.h"
|
#include "Foundation/NSKeyedArchiver.h"
|
||||||
|
|
||||||
|
#include "GSPrivate.h"
|
||||||
|
|
||||||
static SEL eqSel;
|
static SEL eqSel;
|
||||||
static SEL oaiSel;
|
static SEL oaiSel;
|
||||||
|
|
||||||
|
@ -54,39 +56,10 @@ static Class GSInlineArrayClass;
|
||||||
@interface GSArrayEnumeratorReverse : GSArrayEnumerator
|
@interface GSArrayEnumeratorReverse : GSArrayEnumerator
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
@interface GSArray : NSArray
|
|
||||||
{
|
|
||||||
@public
|
|
||||||
id *_contents_array;
|
|
||||||
unsigned _count;
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface GSInlineArray : GSArray
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface GSMutableArray : NSMutableArray
|
|
||||||
{
|
|
||||||
@public
|
|
||||||
id *_contents_array;
|
|
||||||
unsigned _count;
|
|
||||||
unsigned _capacity;
|
|
||||||
int _grow_factor;
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
@interface GSMutableArray (GSArrayBehavior)
|
@interface GSMutableArray (GSArrayBehavior)
|
||||||
- (void) _raiseRangeExceptionWithIndex: (unsigned)index from: (SEL)sel;
|
- (void) _raiseRangeExceptionWithIndex: (unsigned)index from: (SEL)sel;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface GSPlaceholderArray : NSArray
|
|
||||||
{
|
|
||||||
}
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation GSArray
|
@implementation GSArray
|
||||||
|
|
||||||
- (void) _raiseRangeExceptionWithIndex: (unsigned)index from: (SEL)sel
|
- (void) _raiseRangeExceptionWithIndex: (unsigned)index from: (SEL)sel
|
||||||
|
|
|
@ -48,6 +48,38 @@
|
||||||
|
|
||||||
|
|
||||||
#include "GNUstepBase/GSObjCRuntime.h"
|
#include "GNUstepBase/GSObjCRuntime.h"
|
||||||
|
|
||||||
|
#include "Foundation/NSArray.h"
|
||||||
|
|
||||||
|
|
||||||
|
@interface GSArray : NSArray
|
||||||
|
{
|
||||||
|
@public
|
||||||
|
id *_contents_array;
|
||||||
|
unsigned _count;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface GSMutableArray : NSMutableArray
|
||||||
|
{
|
||||||
|
@public
|
||||||
|
id *_contents_array;
|
||||||
|
unsigned _count;
|
||||||
|
unsigned _capacity;
|
||||||
|
int _grow_factor;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface GSInlineArray : GSArray
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface GSPlaceholderArray : NSArray
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
#include "Foundation/NSString.h"
|
#include "Foundation/NSString.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -285,6 +317,34 @@ GSPrivateIsByteEncoding(NSStringEncoding encoding) GS_ATTRIB_PRIVATE;
|
||||||
BOOL
|
BOOL
|
||||||
GSPrivateIsEncodingSupported(NSStringEncoding encoding) GS_ATTRIB_PRIVATE;
|
GSPrivateIsEncodingSupported(NSStringEncoding encoding) GS_ATTRIB_PRIVATE;
|
||||||
|
|
||||||
|
/* Hash function to hash up to limit bytes from data of specified length.
|
||||||
|
* If the flag is NO then a result of 0 is mapped to 0xffffffff.
|
||||||
|
* This is a pretty useful general purpose hash function.
|
||||||
|
*/
|
||||||
|
static inline unsigned
|
||||||
|
GSPrivateHash(const void *data, unsigned length, unsigned limit, BOOL zero)
|
||||||
|
__attribute__((unused));
|
||||||
|
static inline unsigned
|
||||||
|
GSPrivateHash(const void *data, unsigned length, unsigned limit, BOOL zero)
|
||||||
|
{
|
||||||
|
unsigned ret = length;
|
||||||
|
unsigned l = length;
|
||||||
|
|
||||||
|
if (limit < length)
|
||||||
|
{
|
||||||
|
l = limit;
|
||||||
|
}
|
||||||
|
while (l-- > 0)
|
||||||
|
{
|
||||||
|
ret = (ret << 5) + ret + ((const unsigned char*)data)[l];
|
||||||
|
}
|
||||||
|
if (ret == 0 && zero == NO)
|
||||||
|
{
|
||||||
|
ret = 0xffffffff;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* load a module into the runtime
|
/* load a module into the runtime
|
||||||
*/
|
*/
|
||||||
long
|
long
|
||||||
|
@ -307,6 +367,11 @@ void GSPrivateNotifyIdle(void) GS_ATTRIB_PRIVATE;
|
||||||
*/
|
*/
|
||||||
BOOL GSPrivateNotifyMore(void) GS_ATTRIB_PRIVATE;
|
BOOL GSPrivateNotifyMore(void) GS_ATTRIB_PRIVATE;
|
||||||
|
|
||||||
|
/* Function to return the hash value for a small integer (used by NSNumber).
|
||||||
|
*/
|
||||||
|
unsigned
|
||||||
|
GSPrivateSmallHash(int n) GS_ATTRIB_PRIVATE;
|
||||||
|
|
||||||
/* Function to append data to an GSStr
|
/* Function to append data to an GSStr
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
|
|
|
@ -79,19 +79,6 @@ extern void GSPropertyListMake(id,NSDictionary*,BOOL,BOOL,unsigned,id*);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@class GSArray;
|
|
||||||
@interface GSArray : NSObject // Help the compiler
|
|
||||||
@end
|
|
||||||
@class GSInlineArray;
|
|
||||||
@interface GSInlineArray : NSObject // Help the compiler
|
|
||||||
@end
|
|
||||||
@class GSMutableArray;
|
|
||||||
@interface GSMutableArray : NSObject // Help the compiler
|
|
||||||
@end
|
|
||||||
@class GSPlaceholderArray;
|
|
||||||
@interface GSPlaceholderArray : NSObject // Help the compiler
|
|
||||||
@end
|
|
||||||
|
|
||||||
static Class NSArrayClass;
|
static Class NSArrayClass;
|
||||||
static Class GSArrayClass;
|
static Class GSArrayClass;
|
||||||
static Class GSInlineArrayClass;
|
static Class GSInlineArrayClass;
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "Foundation/NSException.h"
|
#include "Foundation/NSException.h"
|
||||||
#include "Foundation/NSCoder.h"
|
#include "Foundation/NSCoder.h"
|
||||||
#include "NSConcreteNumber.h"
|
#include "NSConcreteNumber.h"
|
||||||
|
#include "GSPrivate.h"
|
||||||
|
|
||||||
#define TYPE_ORDER 0
|
#define TYPE_ORDER 0
|
||||||
#include "NSConcreteNumberTemplate.m"
|
#include "NSConcreteNumberTemplate.m"
|
||||||
|
|
|
@ -104,7 +104,7 @@
|
||||||
if (data <= GS_SMALL)
|
if (data <= GS_SMALL)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
return GSSmallHash((int)data);
|
return GSPrivateSmallHash((int)data);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "Foundation/NSObjCRuntime.h"
|
#include "Foundation/NSObjCRuntime.h"
|
||||||
|
|
||||||
#include "NSConcreteNumber.h"
|
#include "NSConcreteNumber.h"
|
||||||
|
#include "GSPrivate.h"
|
||||||
|
|
||||||
@interface GSCachedBool : NSBoolNumber
|
@interface GSCachedBool : NSBoolNumber
|
||||||
@end
|
@end
|
||||||
|
@ -152,7 +153,7 @@ GSNumberInfoFromObject(NSNumber *o)
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
GSSmallHash(int n)
|
GSPrivateSmallHash(int n)
|
||||||
{
|
{
|
||||||
return smallHashes[n + GS_SMALL];
|
return smallHashes[n + GS_SMALL];
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,9 +50,6 @@
|
||||||
|
|
||||||
extern BOOL GSScanDouble(unichar*, unsigned, double*);
|
extern BOOL GSScanDouble(unichar*, unsigned, double*);
|
||||||
|
|
||||||
@class GSMutableArray;
|
|
||||||
@interface GSMutableArray : NSObject // Help the compiler
|
|
||||||
@end
|
|
||||||
@class GSMutableDictionary;
|
@class GSMutableDictionary;
|
||||||
@interface GSMutableDictionary : NSObject // Help the compiler
|
@interface GSMutableDictionary : NSObject // Help the compiler
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -49,10 +49,6 @@
|
||||||
@class NSDataMalloc;
|
@class NSDataMalloc;
|
||||||
@interface NSDataMalloc : NSObject // Help the compiler
|
@interface NSDataMalloc : NSObject // Help the compiler
|
||||||
@end
|
@end
|
||||||
@class GSInlineArray;
|
|
||||||
@class GSMutableArray;
|
|
||||||
@interface GSMutableArray : NSObject // Help the compiler
|
|
||||||
@end
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup for inline operation of string map tables.
|
* Setup for inline operation of string map tables.
|
||||||
|
|
|
@ -30,6 +30,9 @@
|
||||||
#include "Foundation/NSKeyValueCoding.h"
|
#include "Foundation/NSKeyValueCoding.h"
|
||||||
#include "Foundation/NSString.h"
|
#include "Foundation/NSString.h"
|
||||||
|
|
||||||
|
#include "GNUstepBase/GSObjCRuntime.h"
|
||||||
|
#include "GSPrivate.h"
|
||||||
|
|
||||||
@implementation NSSortDescriptor
|
@implementation NSSortDescriptor
|
||||||
|
|
||||||
- (BOOL) ascending
|
- (BOOL) ascending
|
||||||
|
@ -72,7 +75,9 @@
|
||||||
|
|
||||||
- (unsigned) hash
|
- (unsigned) hash
|
||||||
{
|
{
|
||||||
return _ascending + (unsigned)(uintptr_t)_selector + [_key hash];
|
const char *sel = GSNameFromSelector(_selector);
|
||||||
|
|
||||||
|
return _ascending + GSPrivateHash(sel, strlen(sel), 16, YES) + [_key hash];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initWithKey: (NSString *) key ascending: (BOOL) ascending
|
- (id) initWithKey: (NSString *) key ascending: (BOOL) ascending
|
||||||
|
@ -123,12 +128,7 @@
|
||||||
{
|
{
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
/* FIXME ... we should use sel_eq to compare selectors, but if we do
|
if (!sel_eq(((NSSortDescriptor*)other)->_selector, _selector))
|
||||||
* our implementation of -hash will be wrong ... so we will need to
|
|
||||||
* store all instances in a set to ensure uniqueness.
|
|
||||||
*/
|
|
||||||
// if (!sel_eq(((NSSortDescriptor*)other)->_selector, _selector))
|
|
||||||
if (((NSSortDescriptor*)other)->_selector != _selector)
|
|
||||||
{
|
{
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
@ -238,139 +238,100 @@ SortObjectsWithDescriptor(id *objects,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds all objects in the provided range of the objects array that
|
|
||||||
* are next to each other and evaluate with the provided sortDescriptor
|
|
||||||
* as being NSOrderedSame, records their ranges in the provided
|
|
||||||
* recordedRanges array (enlarging it as necessary) and adjusts the
|
|
||||||
* numRanges argument to indicate the new size of the range array.
|
|
||||||
* A pointer to the new location of the array of ranges is returned.
|
|
||||||
*/
|
|
||||||
static NSRange *
|
|
||||||
FindEqualityRanges(id *objects,
|
|
||||||
NSRange searchRange,
|
|
||||||
NSSortDescriptor *sortDescriptor,
|
|
||||||
NSRange *ranges,
|
|
||||||
unsigned int *numRanges)
|
|
||||||
{
|
|
||||||
unsigned int i = searchRange.location;
|
|
||||||
unsigned int n = NSMaxRange(searchRange);
|
|
||||||
|
|
||||||
if (n > 1)
|
|
||||||
{
|
|
||||||
while (i < n - 1)
|
|
||||||
{
|
|
||||||
unsigned int j;
|
|
||||||
|
|
||||||
for (j = i + 1;
|
|
||||||
j < n &&
|
|
||||||
[sortDescriptor compareObject: objects[i] toObject: objects[j]]
|
|
||||||
== NSOrderedSame;
|
|
||||||
j++);
|
|
||||||
|
|
||||||
if (j - i > 1)
|
|
||||||
{
|
|
||||||
(*numRanges)++;
|
|
||||||
ranges = (NSRange *) objc_realloc(ranges, (*numRanges) *
|
|
||||||
sizeof(NSRange));
|
|
||||||
ranges[(*numRanges)-1].location = i;
|
|
||||||
ranges[(*numRanges)-1].length = j - i;
|
|
||||||
|
|
||||||
i = j;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ranges;
|
|
||||||
}
|
|
||||||
|
|
||||||
@implementation NSArray (NSSortDescriptorSorting)
|
@implementation NSArray (NSSortDescriptorSorting)
|
||||||
|
|
||||||
- (NSArray *) sortedArrayUsingDescriptors: (NSArray *) sortDescriptors
|
- (NSArray *) sortedArrayUsingDescriptors: (NSArray *) sortDescriptors
|
||||||
{
|
{
|
||||||
NSMutableArray * sortedArray = [NSMutableArray arrayWithArray: self];
|
NSMutableArray *sortedArray = [GSMutableArray arrayWithArray: self];
|
||||||
|
|
||||||
[sortedArray sortUsingDescriptors: sortDescriptors];
|
[sortedArray sortUsingDescriptors: sortDescriptors];
|
||||||
|
|
||||||
return [sortedArray makeImmutableCopyOnFail:NO];
|
return [sortedArray makeImmutableCopyOnFail: NO];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
/* Sort the objects in range using the first descriptor and, if there
|
||||||
|
* are more descriptors, recursively call the function to sort each range
|
||||||
|
* of adhacent equal objects using the remaining descriptors.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
SortRange(id *objects, NSRange range, id *descriptors,
|
||||||
|
unsigned numDescriptors)
|
||||||
|
{
|
||||||
|
NSSortDescriptor *sd = (NSSortDescriptor*)descriptors[0];
|
||||||
|
|
||||||
|
SortObjectsWithDescriptor(objects, range, sd);
|
||||||
|
if (numDescriptors > 1)
|
||||||
|
{
|
||||||
|
unsigned start = range.location;
|
||||||
|
unsigned finish = NSMaxRange(range);
|
||||||
|
|
||||||
|
while (start < finish)
|
||||||
|
{
|
||||||
|
unsigned pos = start + 1;
|
||||||
|
|
||||||
|
/* Find next range of adjacent objects.
|
||||||
|
*/
|
||||||
|
while (pos < finish
|
||||||
|
&& [sd compareObject: objects[start]
|
||||||
|
toObject: objects[pos]] == NSOrderedSame)
|
||||||
|
{
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sort the range using remaining descriptors.
|
||||||
|
*/
|
||||||
|
if (pos - start > 1)
|
||||||
|
{
|
||||||
|
SortRange(objects, NSMakeRange(start, pos - start),
|
||||||
|
descriptors + 1, numDescriptors - 1);
|
||||||
|
}
|
||||||
|
start = pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@implementation NSMutableArray (NSSortDescriptorSorting)
|
@implementation NSMutableArray (NSSortDescriptorSorting)
|
||||||
|
|
||||||
/**
|
- (void) sortUsingDescriptors: (NSArray *)sortDescriptors
|
||||||
* This method works like this: first, it sorts the entire
|
|
||||||
* contents of the array using the first sort descriptor. Then,
|
|
||||||
* after each sort-run, it looks whether there are sort
|
|
||||||
* descriptors left to process, and if yes, looks at the partially
|
|
||||||
* sorted array, finds all portions in it which are equal
|
|
||||||
* (evaluate to NSOrderedSame) and applies the following
|
|
||||||
* descriptor onto them. It repeats this either until all
|
|
||||||
* descriptors have been applied or there are no more equal
|
|
||||||
* portions (equality ranges) left in the array.
|
|
||||||
*/
|
|
||||||
- (void) sortUsingDescriptors: (NSArray *) sortDescriptors
|
|
||||||
{
|
{
|
||||||
id *objects;
|
unsigned count = [self count];
|
||||||
unsigned int count;
|
unsigned numDescriptors = [sortDescriptors count];
|
||||||
|
|
||||||
NSRange *equalityRanges;
|
if (count > 1 && numDescriptors > 0)
|
||||||
unsigned int numEqualityRanges;
|
|
||||||
|
|
||||||
unsigned int i, n;
|
|
||||||
|
|
||||||
count = [self count];
|
|
||||||
objects = (id *) objc_calloc(count, sizeof(id));
|
|
||||||
[self getObjects: objects];
|
|
||||||
|
|
||||||
equalityRanges = (NSRange *) objc_calloc(1, sizeof(NSRange));
|
|
||||||
equalityRanges[0].location = 0;
|
|
||||||
equalityRanges[0].length = count;
|
|
||||||
numEqualityRanges = 1;
|
|
||||||
|
|
||||||
for (i = 0, n = [sortDescriptors count]; i < n && equalityRanges != NULL; i++)
|
|
||||||
{
|
{
|
||||||
unsigned int j;
|
id descriptors[numDescriptors];
|
||||||
NSSortDescriptor *sortDescriptor = [sortDescriptors objectAtIndex: i];
|
GS_BEGINIDBUF(objects, count);
|
||||||
|
NSArray *a;
|
||||||
|
|
||||||
// pass through all equality ranges and sort each of them
|
[self getObjects: objects];
|
||||||
for (j = 0; j < numEqualityRanges; j++)
|
[sortDescriptors getObjects: descriptors];
|
||||||
{
|
SortRange(objects, NSMakeRange(0, count), descriptors, numDescriptors);
|
||||||
SortObjectsWithDescriptor(objects, equalityRanges[j],
|
a = [[NSArray alloc] initWithObjects: objects count: count];
|
||||||
sortDescriptor);
|
[self setArray: a];
|
||||||
}
|
RELEASE(a);
|
||||||
|
GS_ENDIDBUF();
|
||||||
// then, if there are sort descriptors left to process
|
}
|
||||||
if (i < n - 1)
|
}
|
||||||
// reconstruct the equality ranges anew.
|
|
||||||
{
|
@end
|
||||||
NSRange *newRanges = NULL;
|
|
||||||
unsigned newNumRanges = 0;
|
@implementation GSMutableArray (NSSortDescriptorSorting)
|
||||||
|
|
||||||
// process only contents of old equality ranges
|
- (void) sortUsingDescriptors: (NSArray *)sortDescriptors
|
||||||
for (j = 0; j < numEqualityRanges; j++)
|
{
|
||||||
{
|
unsigned dCount = [sortDescriptors count];
|
||||||
newRanges = FindEqualityRanges(objects, equalityRanges[j],
|
|
||||||
sortDescriptor, newRanges, &newNumRanges);
|
if (_count > 1 && dCount > 0)
|
||||||
}
|
{
|
||||||
|
GS_BEGINIDBUF(descriptors, dCount);
|
||||||
objc_free(equalityRanges);
|
|
||||||
equalityRanges = newRanges;
|
[sortDescriptors getObjects: descriptors];
|
||||||
numEqualityRanges = newNumRanges;
|
SortRange(_contents_array, NSMakeRange(0, _count), descriptors, dCount);
|
||||||
}
|
|
||||||
|
GS_ENDIDBUF();
|
||||||
}
|
}
|
||||||
|
|
||||||
objc_free(equalityRanges);
|
|
||||||
|
|
||||||
// now, reconstruct our contents according to the sorted object buffer
|
|
||||||
[self setArray: [NSArray arrayWithObjects: objects count: count]];
|
|
||||||
|
|
||||||
objc_free(objects);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue