home *** CD-ROM | disk | FTP | other *** search
- //
- // MiscObjectRecycler.h -- a category to speed up alloc/free of piddly objects
- // Written by Don Yacktman (c) 1994 by Don Yacktman.
- // Version 1.0. All rights reserved.
- //
- // This notice may not be removed from this source code.
- //
- // This object is included in the MiscKit by permission from the author
- // and its use is governed by the MiscKit license, found in the file
- // "LICENSE.rtf" in the MiscKit distribution. Please refer to that file
- // for a list of all applicable permissions and restrictions.
- //
-
- #import <misckit/misckit.h>
- #import <objc/objc-runtime.h>
-
- //#define MISC_SLOW_BUT_SAFE // define if you are paranoid
-
- static id _recyclerHash = nil; // holds all the List objects (recyclers),
- // one for each class. They are created on demand, so a class
- // that doesn't recycle won't take up extra space.
-
- @interface Object(MiscObjectRecyclerPrivate)
-
- + recyclers; // returns the HashTable full of recyclers
-
- @end
-
- @implementation Object(MiscObjectRecycler)
-
- + recyclers
- {
- if (!_recyclerHash) {
- _recyclerHash = [[HashTable alloc]
- initKeyDesc:"@" valueDesc:"@" capacity:0];
- }
- return _recyclerHash;
- }
-
- + recycler
- {
- return [self recyclerForClass:self];
- }
-
- + recyclerForClass:aClass
- {
- id theRecycler = [[self recyclers] valueForKey:aClass];
- if (!theRecycler) {
- theRecycler = [[List alloc] initCount:0];
- [[self recyclers] insertKey:aClass value:theRecycler];
- }
- return theRecycler;
- }
-
- + recyclerForClassName:(const char *)className;
- {
- return [self recyclerForClass:objc_lookUpClass(className)];
- }
-
- + newFromRecycler
- { // We remove the last object because it is faster. If we took
- // the first object, the list would shift all the objects down
- // to fill the hole. This way there's no shifting. O(1) instead
- // of O(n) could make a big difference here!
- id ret = nil;
- id theObject = [[self recycler] removeLastObject];
- if (!theObject) {
- theObject = [self alloc];
- ret = [self firstInitObject:theObject];
- } else {
- ret = [self reInitObject:theObject];
- }
- return ret;
- }
-
- + reInitObject:anObject
- // override this if you need to re-init your object in a special way
- {
- return [anObject init];
- }
-
- + firstInitObject:anObject
- // override this if you need to init your object in a special way
- // the first time around
- {
- return [anObject init];
- }
-
- - recycle
- { // just like free, we go out or circulation, but we don't free.
- // we just wait around until they need us again.
- // We add it as the last object because it is faster. If we inserted
- // it as the first object, the list would shift all the objects up
- // to make room. This way there's no shifting. O(1) instead
- // of O(n) could make a big difference here!
- #ifdef MISC_SLOW_BUT_SAFE
- [[[self class] recycler] addObjectIfAbsent:self];
- #else
- [[[self class] recycler] addObject:self];
- #endif
- return nil;
- }
-
- @end
-