mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
Added uniquing support for deserialized strings.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@4335 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
e0e4bd85b2
commit
a7ba6ae51d
3 changed files with 161 additions and 0 deletions
|
@ -1,3 +1,8 @@
|
|||
Tue Jun 2 10:50:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
|
||||
* Source/NSSerializer.m: Added uniquing for deserialized strings.
|
||||
* Source/include/NSSerialization.h: likewise.
|
||||
|
||||
Tue Jun 2 5:45:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
|
||||
* Source/TcpPort.m: Fixed to compile cleanly under cygwin.
|
||||
|
|
|
@ -80,4 +80,29 @@
|
|||
|
||||
@end
|
||||
|
||||
#ifndef NO_GNUSTEP
|
||||
/*
|
||||
* GNUstep extends deserialization by having the option to make the
|
||||
* resulting data more compact by ensuring that repeated strings
|
||||
* are only stored once. If the property-list has a lot of repeated
|
||||
* strings in it, this will be more space efficient but it will be
|
||||
* slower (though other parts of your code may speed up through more
|
||||
* efficient equality testing of uniqued strings).
|
||||
* The default is NOT to deserialize uniqued strings.
|
||||
*
|
||||
* The [+uniquing:] method turns uniquing on/off. Turning off uniquing
|
||||
* destroys the NSCountedSet used for uniquing.
|
||||
* The [+purge] method lets you remove some of the objects from the
|
||||
* NSCountedSet used for uniquing. The count of each string in the
|
||||
* set is decreased, so that strings that have only been deserialized
|
||||
* once are removed.
|
||||
*/
|
||||
@interface NSDeserializer (GNUstep)
|
||||
+ (void) _becomeThreaded: (id)notification; /* private */
|
||||
+ (void) purge;
|
||||
+ (void) uniquing: (BOOL)flag;
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __NSSerialization_h_GNUSTEP_BASE_INCLUDE */
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
#include <Foundation/NSString.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSProxy.h>
|
||||
#include <Foundation/NSLock.h>
|
||||
#include <Foundation/NSSet.h>
|
||||
#include <Foundation/NSThread.h>
|
||||
#include <Foundation/NSNotificationQueue.h>
|
||||
|
||||
#include <base/NSGArray.h>
|
||||
#include <base/NSGCString.h>
|
||||
|
@ -343,6 +347,12 @@ static BOOL shouldBeCompact = NO;
|
|||
|
||||
|
||||
|
||||
/*
|
||||
* Class variables for uniquing incoming strings.
|
||||
*/
|
||||
static NSRecursiveLock *uniqueLock = nil;
|
||||
static NSCountedSet *uniqueSet = nil;
|
||||
|
||||
/*
|
||||
* Variables to cache class information.
|
||||
*/
|
||||
|
@ -425,6 +435,31 @@ deserializeFromInfo(_NSDeserializerInfo* info)
|
|||
(*info->debImp)(info->data, debSel, b, size, info->cursor);
|
||||
s = (NSGCString*)NSAllocateObject(CSCls, 0, NSDefaultMallocZone());
|
||||
s = (*csInitImp)(s, csInitSel, b, size-1, NSDefaultMallocZone());
|
||||
|
||||
/*
|
||||
* If we are supposed to be doing uniquing of strings, handle it.
|
||||
*/
|
||||
if (uniqueSet != nil)
|
||||
{
|
||||
id uniqued;
|
||||
|
||||
if (uniqueLock != nil)
|
||||
[uniqueLock lock];
|
||||
[uniqueSet addObject: s];
|
||||
uniqued = [uniqueSet member: s];
|
||||
if (uniqueLock != nil)
|
||||
[uniqueLock unlock];
|
||||
if (uniqued != s)
|
||||
{
|
||||
RELEASE(s);
|
||||
s = RETAIN(uniqued);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If uniquing was done on serialisation, store the string for
|
||||
* later reference.
|
||||
*/
|
||||
if (info->didUnique)
|
||||
FastArrayAddItem(&info->array, (FastArrayItem)s);
|
||||
return s;
|
||||
|
@ -438,6 +473,31 @@ deserializeFromInfo(_NSDeserializerInfo* info)
|
|||
(*info->debImp)(info->data, debSel, b, size*2, info->cursor);
|
||||
s = (NSGString*)NSAllocateObject(USCls, 0, NSDefaultMallocZone());
|
||||
s = (*usInitImp)(s, usInitSel, b, size, NSDefaultMallocZone());
|
||||
|
||||
/*
|
||||
* If we are supposed to be doing uniquing of strings, handle it.
|
||||
*/
|
||||
if (uniqueSet != nil)
|
||||
{
|
||||
id uniqued;
|
||||
|
||||
if (uniqueLock != nil)
|
||||
[uniqueLock lock];
|
||||
[uniqueSet addObject: s];
|
||||
uniqued = [uniqueSet member: s];
|
||||
if (uniqueLock != nil)
|
||||
[uniqueLock unlock];
|
||||
if (uniqued != s)
|
||||
{
|
||||
RELEASE(s);
|
||||
s = RETAIN(uniqued);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If uniquing was done on serialisation, store the string for
|
||||
* later reference.
|
||||
*/
|
||||
if (info->didUnique)
|
||||
FastArrayAddItem(&info->array, (FastArrayItem)s);
|
||||
return s;
|
||||
|
@ -632,6 +692,18 @@ deserializeFromInfo(_NSDeserializerInfo* info)
|
|||
maInitImp = [MACls instanceMethodForSelector: maInitSel];
|
||||
idInitImp = [IDCls instanceMethodForSelector: idInitSel];
|
||||
mdInitImp = [MDCls instanceMethodForSelector: mdInitSel];
|
||||
if ([NSThread isMultiThreaded])
|
||||
{
|
||||
[self _becomeThreaded: nil];
|
||||
}
|
||||
else
|
||||
{
|
||||
[NSNotificationCenter
|
||||
addObserver: self
|
||||
selector: @selector(_becomeThreaded:)
|
||||
name: NSWillBecomeMultiThreadedNotification
|
||||
object: nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -693,3 +765,62 @@ deserializeFromInfo(_NSDeserializerInfo* info)
|
|||
}
|
||||
@end
|
||||
|
||||
@implementation NSDeserializer (GNUstep)
|
||||
/*
|
||||
* If we are multi-threaded, we must guard access to the uniquing set.
|
||||
*/
|
||||
+ (void) _becomeThreaded: (id)notification
|
||||
{
|
||||
uniqueLock = [NSRecursiveLock new];
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove one copy of each object in the uniquing set, or remove all
|
||||
* objects if the flag is YES.
|
||||
*/
|
||||
+ (void) purge
|
||||
{
|
||||
if (uniqueSet)
|
||||
{
|
||||
NSArray *all;
|
||||
id obj;
|
||||
unsigned i;
|
||||
|
||||
if (uniqueLock != nil)
|
||||
[uniqueLock lock];
|
||||
all = [uniqueSet allObjects];
|
||||
for (i = [all count]; i > 0; i--)
|
||||
{
|
||||
[uniqueSet removeObject: [all objectAtIndex: i-1]];
|
||||
}
|
||||
if (uniqueLock != nil)
|
||||
[uniqueLock unlock];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Turn uniquing of deserialized strings on/off
|
||||
*/
|
||||
+ (void) uniquing: (BOOL)flag
|
||||
{
|
||||
if (uniqueLock != nil)
|
||||
[uniqueLock lock];
|
||||
if (flag)
|
||||
{
|
||||
if (uniqueSet == nil)
|
||||
{
|
||||
uniqueSet = [NSCountedSet new];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (uniqueSet != nil)
|
||||
{
|
||||
DESTROY(uniqueSet);
|
||||
}
|
||||
}
|
||||
if (uniqueLock != nil)
|
||||
[uniqueLock unlock];
|
||||
}
|
||||
@end
|
||||
|
||||
|
|
Loading…
Reference in a new issue