home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1995 August / NEBULA.bin / SourceCode / MiscKit1.2.6 / Source / MiscObjectRecycler.m < prev    next >
Encoding:
Text File  |  1994-02-03  |  2.8 KB  |  105 lines

  1. //
  2. //    MiscObjectRecycler.h -- a category to speed up alloc/free of piddly objects
  3. //        Written by Don Yacktman (c) 1994 by Don Yacktman.
  4. //                Version 1.0.  All rights reserved.
  5. //
  6. //        This notice may not be removed from this source code.
  7. //
  8. //    This object is included in the MiscKit by permission from the author
  9. //    and its use is governed by the MiscKit license, found in the file
  10. //    "LICENSE.rtf" in the MiscKit distribution.  Please refer to that file
  11. //    for a list of all applicable permissions and restrictions.
  12. //    
  13.  
  14. #import <misckit/misckit.h>
  15. #import <objc/objc-runtime.h>
  16.  
  17. //#define MISC_SLOW_BUT_SAFE // define if you are paranoid
  18.  
  19. static id _recyclerHash = nil;  // holds all the List objects (recyclers),
  20.         // one for each class.  They are created on demand, so a class
  21.         // that doesn't recycle won't take up extra space.
  22.  
  23. @interface Object(MiscObjectRecyclerPrivate)
  24.  
  25. + recyclers; // returns the HashTable full of recyclers
  26.  
  27. @end
  28.  
  29. @implementation Object(MiscObjectRecycler)
  30.  
  31. + recyclers
  32. {
  33.     if (!_recyclerHash) {
  34.         _recyclerHash = [[HashTable alloc]
  35.                 initKeyDesc:"@" valueDesc:"@" capacity:0];
  36.     }
  37.     return _recyclerHash;
  38. }
  39.  
  40. + recycler
  41. {
  42.     return [self recyclerForClass:self];
  43. }
  44.  
  45. + recyclerForClass:aClass
  46. {
  47.     id theRecycler = [[self recyclers] valueForKey:aClass];
  48.     if (!theRecycler) {
  49.         theRecycler = [[List alloc] initCount:0];
  50.         [[self recyclers] insertKey:aClass value:theRecycler];
  51.     }
  52.     return theRecycler;
  53. }
  54.  
  55. + recyclerForClassName:(const char *)className;
  56. {
  57.     return [self recyclerForClass:objc_lookUpClass(className)];
  58. }
  59.  
  60. + newFromRecycler
  61. {    // We remove the last object because it is faster.  If we took
  62.     // the first object, the list would shift all the objects down
  63.     // to fill the hole.  This way there's no shifting.  O(1) instead
  64.     // of O(n) could make a big difference here!
  65.     id ret = nil;
  66.     id theObject = [[self recycler] removeLastObject];
  67.     if (!theObject) {
  68.         theObject = [self alloc];
  69.         ret = [self firstInitObject:theObject];
  70.     } else {
  71.         ret = [self reInitObject:theObject];
  72.     }
  73.     return ret;
  74. }
  75.  
  76. + reInitObject:anObject
  77. // override this if you need to re-init your object in a special way
  78. {
  79.     return [anObject init];
  80. }
  81.  
  82. + firstInitObject:anObject
  83. // override this if you need to init your object in a special way
  84. // the first time around
  85. {
  86.     return [anObject init];
  87. }
  88.  
  89. - recycle
  90. {    // just like free, we go out or circulation, but we don't free.
  91.     // we just wait around until they need us again.
  92.     // We add it as the last object because it is faster.  If we inserted
  93.     // it as the first object, the list would shift all the objects up
  94.     // to make room.  This way there's no shifting.  O(1) instead
  95.     // of O(n) could make a big difference here!
  96. #ifdef MISC_SLOW_BUT_SAFE
  97.     [[[self class] recycler] addObjectIfAbsent:self];
  98. #else
  99.     [[[self class] recycler] addObject:self];
  100. #endif
  101.     return nil;
  102. }
  103.  
  104. @end
  105.