PageRenderTime 38ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/antlr-3.4/runtime/ObjC/Framework/ACBTree.m

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Objective C | 721 lines | 597 code | 60 blank | 64 comment | 168 complexity | b18aaf8e1d6913759468490a9f80d5d1 MD5 | raw file
  1. //
  2. // ACBTree.m
  3. // ST4
  4. //
  5. // Created by Alan Condit on 4/18/11.
  6. // Copyright 2011 Alan Condit. All rights reserved.
  7. //
  8. #import <Cocoa/Cocoa.h>
  9. #import "ACBTree.h"
  10. #import "AMutableDictionary.h"
  11. #import "ANTLRRuntimeException.h"
  12. @class AMutableDictionary;
  13. @implementation ACBKey
  14. static NSInteger RECNUM = 0;
  15. @synthesize recnum;
  16. @synthesize key;
  17. + (ACBKey *)newKey
  18. {
  19. return [[ACBKey alloc] init];
  20. }
  21. + (ACBKey *)newKeyWithKStr:(NSString *)aKey
  22. {
  23. return [[ACBKey alloc] initWithKStr:(NSString *)aKey];
  24. }
  25. - (id) init
  26. {
  27. self =[super init];
  28. if ( self != nil ) {
  29. recnum = RECNUM++;
  30. }
  31. return self;
  32. }
  33. - (id) initWithKStr:(NSString *)aKey
  34. {
  35. self =[super init];
  36. if ( self != nil ) {
  37. NSInteger len;
  38. recnum = RECNUM++;
  39. key = aKey;
  40. len = [aKey length];
  41. if ( len >= BTKeySize ) {
  42. len = BTKeySize - 1;
  43. }
  44. strncpy( kstr, [aKey cStringUsingEncoding:NSASCIIStringEncoding], len);
  45. kstr[len] = '\0';
  46. }
  47. return self;
  48. }
  49. @end
  50. @implementation ACBTree
  51. @synthesize dict;
  52. @synthesize lnode;
  53. @synthesize rnode;
  54. @synthesize keys;
  55. @synthesize btNodes;
  56. @synthesize lnodeid;
  57. @synthesize rnodeid;
  58. @synthesize nodeid;
  59. @synthesize nodeType;
  60. @synthesize numkeys;
  61. @synthesize numrecs;
  62. @synthesize updtd;
  63. @synthesize keylen;
  64. @synthesize kidx;
  65. + (ACBTree *) newNodeWithDictionary:(AMutableDictionary *)theDict
  66. {
  67. return [[ACBTree alloc] initWithDictionary:theDict];
  68. }
  69. - (id)initWithDictionary:(AMutableDictionary *)theDict
  70. {
  71. self = [super init];
  72. if (self) {
  73. // Initialization code here.
  74. dict = theDict;
  75. nodeid = theDict.nxt_nodeid++;
  76. keys = keyArray;
  77. btNodes = btNodeArray;
  78. if ( nodeid == 0 ) {
  79. numkeys = 0;
  80. }
  81. }
  82. return self;
  83. }
  84. - (ACBTree *)createnode:(ACBKey *)kp
  85. {
  86. ACBTree *tmp;
  87. tmp = [ACBTree newNodeWithDictionary:dict];
  88. tmp.nodeType = nodeType;
  89. tmp.lnode = self;
  90. tmp.rnode = self.rnode;
  91. self.rnode = tmp;
  92. //tmp.btNodes[0] = self;
  93. //tmp.keys[0] = kp;
  94. tmp.updtd = YES;
  95. tmp.numrecs = ((nodeType == LEAF)?1:numrecs);
  96. updtd = YES;
  97. tmp.numkeys = 1;
  98. [tmp retain];
  99. return(tmp);
  100. }
  101. - (ACBTree *)deletekey:(NSString *)dkey
  102. {
  103. ACBKey /* *del, */ *dkp;
  104. ACBTree *told, *sNode;
  105. BOOL mustRelease = NO;
  106. if ( [dkey isKindOfClass:[NSString class]] ) {
  107. dkp = [ACBKey newKeyWithKStr:dkey];
  108. mustRelease = YES;
  109. }
  110. else if ( [dkey isKindOfClass:[ACBKey class]] )
  111. dkp = (ACBKey *)dkey;
  112. else
  113. @throw [ANTLRIllegalArgumentException newException:[NSString stringWithFormat:@"Don't understand this key:\"%@\"", dkey]];
  114. sNode = [self search:dkp.key];
  115. if ( sNode == nil || [sNode searchnode:dkp.key match:YES] == FAILURE ) {
  116. if ( mustRelease ) [dkp release];
  117. return(self);
  118. }
  119. told = dict.root;
  120. /* del = */[self internaldelete:dkp];
  121. /* check for shrink at the root */
  122. if ( numkeys == 1 && nodeType != LEAF ) {
  123. told = btNodes[0];
  124. told.nodeid = 1;
  125. told.updtd = YES;
  126. dict.root = told;
  127. }
  128. #ifdef DONTUSENOMO
  129. if (debug == 'd') [self printtree];
  130. #endif
  131. if ( mustRelease ) [dkp release];
  132. return(told);
  133. }
  134. /** insertKey is the insertion entry point
  135. * It determines if the key exists in the tree already
  136. * it calls internalInsert to determine if the key already exists in the tree,
  137. * and returns the node to be updated
  138. */
  139. - (ACBTree *)insertkey:(ACBKey *)kp value:(id)value
  140. {
  141. ACBTree *tnew, *q;
  142. NSInteger h, nodeNum;
  143. tnew = self;
  144. q = [self internalinsert:kp value:value split:&h];
  145. /* check for growth at the root */
  146. if ( q != nil ) {
  147. tnew = [[ACBTree newNodeWithDictionary:dict] retain];
  148. tnew.nodeType = BTNODE;
  149. nodeNum = tnew.nodeid;
  150. tnew.nodeid = 0;
  151. self.nodeid = nodeNum;
  152. [tnew insert:self.keys[numkeys-1] value:self index:0 split:&h];
  153. [tnew insert:q.keys[q.numkeys-1] value:q index:1 split:&h];
  154. tnew.numrecs = self.numrecs + q.numrecs;
  155. tnew.lnodeid = self.nodeid;
  156. tnew.rnodeid = self.rnodeid;
  157. self.rnodeid = tnew.nodeid;
  158. tnew.lnode = self;
  159. tnew.rnode = self.rnode;
  160. self.rnode = tnew;
  161. /* affected by nodeid swap */
  162. // newnode.lnodeid = tnew.btNodes[0].nodeid;
  163. }
  164. //dict.root = t;
  165. //l.reccnt++;
  166. return(tnew);
  167. }
  168. - (ACBTree *)search:(NSString *)kstr
  169. {
  170. NSInteger i, ret;
  171. NSInteger srchlvl = 0;
  172. ACBTree *t;
  173. t = self;
  174. if ( self.numkeys == 0 && self.nodeType == LEAF )
  175. return nil;
  176. while (t != nil) {
  177. for (i = 0; i < t.numkeys; i++) {
  178. ret = [t.keys[i].key compare:kstr];
  179. if ( ret >= 0 ) {
  180. if ( t.nodeType == LEAF ) {
  181. if ( ret == 0 ) return (t); /* node containing keyentry found */
  182. else return nil;
  183. }
  184. else {
  185. break;
  186. }
  187. }
  188. }
  189. srchlvl++;
  190. if ( t.nodeType == BTNODE ) t = t.btNodes[i];
  191. else {
  192. t = nil;
  193. }
  194. }
  195. return(nil); /* entry not found */
  196. }
  197. /** SEARCHNODE
  198. * calling parameters --
  199. * BKEY PTR for key to search for.
  200. * TYPE for exact match(YES) or position(NO)
  201. * returns -- i
  202. * i == FAILURE when match required but does not exist.
  203. * i == t.numkeys if no existing insertion branch found.
  204. * otherwise i == insertion branch.
  205. */
  206. - (NSInteger)searchnode:(NSString *)kstr match:(BOOL)match
  207. {
  208. NSInteger i, ret;
  209. for ( i = 0; i < numkeys; i++ ) {
  210. ret = [keys[i].key compare:kstr];
  211. if ( ret >= 0 ) { /* key node found */
  212. if ( ret == 0 && match == NO ) {
  213. return FAILURE;
  214. }
  215. else if ( ret > 0 && match == YES ) {
  216. return FAILURE;
  217. }
  218. break;
  219. }
  220. }
  221. if ( i == numkeys && match == YES ) {
  222. i = FAILURE;
  223. }
  224. return(i);
  225. }
  226. - (ACBKey *)internaldelete:(ACBKey *)dkp
  227. {
  228. NSInteger i, nkey;
  229. __strong ACBKey *del = nil;
  230. ACBTree *tsb;
  231. NSInteger srchlvl = 0;
  232. /* find deletion branch */
  233. if ( self.nodeType != LEAF ) {
  234. srchlvl++;
  235. /* search for end of tree */
  236. i = [self searchnode:dkp.key match:NO];
  237. del = [btNodes[i] internaldelete:dkp];
  238. srchlvl--;
  239. /* if not LEAF propagate back high key */
  240. tsb = btNodes[i];
  241. nkey = tsb.numkeys - 1;
  242. }
  243. /*** the bottom of the tree has been reached ***/
  244. else { /* set up deletion ptrs */
  245. if ( [self delfrmnode:dkp] == SUCCESS ) {
  246. if ( numkeys < BTHNODESIZE+1 ) {
  247. del = dkp;
  248. }
  249. else {
  250. del = nil;
  251. }
  252. dkp.recnum = nodeid;
  253. return(del);
  254. }
  255. }
  256. /*** indicate deletion to be done ***/
  257. if ( del != nil ) {
  258. /*** the key in "del" has to be deleted from in present node ***/
  259. if ( btNodes[i].numkeys >= BTHNODESIZE+1 ) {
  260. /* node does not need balancing */
  261. del = nil;
  262. self.keys[i] = tsb.keys[nkey];
  263. }
  264. else { /* node requires balancing */
  265. if ( i == 0 ) {
  266. [self rotateright:0];
  267. self.btNodes[0] = tsb;
  268. } else if ( i < numkeys-1 ) { /* look to the right first */
  269. if ( self.btNodes[i+1].numkeys > BTHNODESIZE+1 ) { /* carry from right */
  270. [self borrowright:i];
  271. }
  272. else { /* merge present node with right node */
  273. [self mergenode:i];
  274. }
  275. }
  276. else { /* look to the left */
  277. if ( i > 0 ) { /* carry or merge with left node */
  278. if ( self.btNodes[i-1].numkeys > BTHNODESIZE+1 ) { /* carry from left */
  279. [self borrowleft:i];
  280. }
  281. else { /*** merge present node with left node ***/
  282. i--;
  283. [self mergenode:i];
  284. tsb = self.btNodes[i];
  285. }
  286. }
  287. }
  288. self.keys[i] = tsb.keys[nkey];
  289. }
  290. }
  291. numrecs--;
  292. updtd = TRUE;
  293. return(del);
  294. }
  295. /** Search key kp on B-tree with root t; if found increment counter.
  296. * otherwise insert an item with key kp in tree. If an ACBKey
  297. * emerges to be passed to a lower level, then assign it to kp;
  298. * h = "tree t has become higher"
  299. */
  300. - (ACBTree *) internalinsert:(ACBKey *)kp value:(id)value split:(NSInteger *)h
  301. {
  302. /* search key ins on node t^; h = false */
  303. NSInteger i, ret;
  304. ACBTree *q, *tmp;
  305. for (i = 0; i < numkeys; i++) {
  306. ret = [keys[i].key compare:kp.key];
  307. if ( ret >= 0 ) {
  308. if ( nodeType == LEAF && ret == 0 ) return (self); /* node containing keyentry found */
  309. break;
  310. }
  311. }
  312. if ( nodeType == LEAF ) { /* key goes in this node */
  313. q = [self insert:kp value:value index:i split:h];
  314. }
  315. else { /* nodeType == BTNODE */
  316. /* key is not on this node */
  317. q = [self.btNodes[i] internalinsert:kp value:value split:h];
  318. if ( *h ) {
  319. [self insert:kp value:q index:i split:h];
  320. }
  321. else {
  322. self.numrecs++;
  323. }
  324. tmp = self.btNodes[numkeys-1];
  325. keys[numkeys-1] = tmp.keys[tmp.numkeys-1];
  326. if ( i != numkeys-1 ) {
  327. tmp = self.btNodes[i];
  328. keys[i] = tmp.keys[tmp.numkeys-1];
  329. }
  330. updtd = YES;
  331. } /* search */
  332. return q;
  333. }
  334. /** Do the actual insertion or split and insert
  335. * insert key to the right of t.keys[hi]
  336. */
  337. - (ACBTree *) insert:(ACBKey *)kp value:(id)value index:(NSInteger)hi split:(NSInteger *)h
  338. {
  339. ACBTree *b;
  340. if ( numkeys < BTNODESIZE ) {
  341. *h = NO;
  342. [self rotateright:hi];
  343. keys[hi] = kp;
  344. btNodes[hi] = value;
  345. numrecs++;
  346. numkeys++;
  347. updtd = YES;
  348. //[kp retain];
  349. return nil;
  350. }
  351. else { /* node t is full; split it and assign the emerging ACBKey to olditem */
  352. b = [self splitnode:hi];
  353. if ( hi <= BTHNODESIZE ) { /* insert key in left page */
  354. [self rotateright:hi];
  355. keys[hi] = kp;
  356. btNodes[hi] = value;
  357. numrecs++;
  358. numkeys++;
  359. }
  360. else { /* insert key in right page */
  361. hi -= BTHNODESIZE;
  362. if ( b.rnode == nil ) hi--;
  363. [b rotateright:hi];
  364. b.keys[hi] = kp;
  365. b.btNodes[hi] = value;
  366. b.numrecs++;
  367. b.numkeys++;
  368. }
  369. numkeys = b.numkeys = BTHNODESIZE+1;
  370. b.updtd = updtd = YES;
  371. }
  372. return b;
  373. } /* insert */
  374. - (void)borrowleft:(NSInteger)i
  375. {
  376. ACBTree *t0, *t1;
  377. NSInteger nkey;
  378. t0 = btNodes[i];
  379. t1 = btNodes[i-1];
  380. nkey = t1.numkeys-1;
  381. [t0 insinnode:t1.keys[nkey] value:t1.btNodes[nkey]];
  382. [t1 delfrmnode:t1.keys[nkey]];
  383. nkey--;
  384. keys[i-1] = t1.keys[nkey];
  385. keys[i-1].recnum = t1.nodeid;
  386. }
  387. - (void)borrowright:(NSInteger)i
  388. {
  389. ACBTree *t0, *t1;
  390. NSInteger nkey;
  391. t0 = btNodes[i];
  392. t1 = btNodes[i+1];
  393. [t0 insinnode:t1.keys[0] value:t1.btNodes[0]];
  394. [t1 delfrmnode:t1.keys[0]];
  395. nkey = t0.numkeys - 1;
  396. keys[i] = t0.keys[nkey];
  397. keys[i].recnum = t0.nodeid;
  398. }
  399. - (NSInteger)delfrmnode:(ACBKey *)ikp
  400. {
  401. NSInteger j;
  402. j = [self searchnode:ikp.key match:YES];
  403. if (j == FAILURE) {
  404. return(FAILURE);
  405. }
  406. ACBKey *k0 = nil;
  407. ACBTree *n0 = nil;
  408. if ( self.nodeType == LEAF ) {
  409. k0 = self.keys[j];
  410. n0 = self.btNodes[j];
  411. }
  412. [self rotateleft:j];
  413. self.numkeys--;
  414. numrecs -= ((self.nodeType == LEAF)?1:btNodes[j].numrecs);
  415. if ( k0 ) [k0 release];
  416. if ( n0 ) [n0 release];
  417. updtd = TRUE;
  418. return(SUCCESS);
  419. }
  420. - (NSInteger)insinnode:(ACBKey *)ikp value:(id)value
  421. {
  422. NSInteger j;
  423. j = [self searchnode:ikp.key match:NO];
  424. [self rotateright:j];
  425. keys[j] = ikp;
  426. btNodes[j] = value;
  427. numkeys++;
  428. if ( nodeType == LEAF ) {
  429. numrecs++;
  430. }
  431. else {
  432. numrecs += btNodes[j].numrecs;
  433. }
  434. updtd = TRUE;
  435. return(j);
  436. }
  437. - (void)mergenode:(NSInteger)i
  438. {
  439. ACBTree *t0, *t1, *tr;
  440. NSInteger j, k, nkeys;
  441. t0 = btNodes[i];
  442. t1 = btNodes[i+1];
  443. /*** move keys and pointers from
  444. t1 node to t0 node ***/
  445. for (j=t0.numkeys, k=0; j < BTNODESIZE && k < t1.numkeys; j++, k++) {
  446. t0.keys[j] = t1.keys[k];
  447. t0.btNodes[j] = t1.btNodes[k];
  448. t0.numkeys++;
  449. }
  450. t0.numrecs += t1.numrecs;
  451. t0.rnode = t1.rnode;
  452. t0.rnodeid = t1.rnodeid;
  453. t0.updtd = YES;
  454. nkeys = t0.numkeys - 1;
  455. keys[i] = t0.keys[nkeys]; /* update key to point to new high key */
  456. [self rotateleft:i+1]; /* copy over the keys and nodes */
  457. t1.nodeType = -1;
  458. if (t1.rnodeid != 0xffff && i < numkeys - 2) {
  459. tr = btNodes[i+1];
  460. tr.lnodeid = t0.nodeid;
  461. tr.lnode = t0;
  462. tr.updtd = YES;
  463. }
  464. self.numkeys--;
  465. updtd = YES;
  466. }
  467. - (ACBTree *)splitnode:(NSInteger)idx
  468. {
  469. ACBTree *t1;
  470. NSInteger j, k;
  471. k = (idx <= BTHNODESIZE) ? BTHNODESIZE : BTHNODESIZE+1;
  472. /*** create new node ***/
  473. // checknode(l, t, k);
  474. t1 = [ACBTree newNodeWithDictionary:dict];
  475. t1.nodeType = nodeType;
  476. t1.rnode = self.rnode;
  477. self.rnode = t1;
  478. t1.lnode = self;
  479. self.updtd = t1.updtd = YES;
  480. /*** move keys and pointers ***/
  481. NSInteger i = 0;
  482. for (j = k; j < BTNODESIZE; j++, i++ ) {
  483. t1.keys[i] = keys[j];
  484. t1.btNodes[i] = btNodes[j];
  485. t1.numrecs += ((nodeType == LEAF) ? 1 : btNodes[j].numrecs);
  486. numrecs -= ((nodeType == LEAF) ? 1 : btNodes[j].numrecs);
  487. keys[j] = nil;
  488. btNodes[j] = nil;
  489. }
  490. t1.numkeys = BTNODESIZE-k;
  491. self.numkeys = k;
  492. return(t1);
  493. }
  494. #ifdef DONTUSENOMO
  495. freetree(l, t)
  496. FIDB *l;
  497. ACBTree *t;
  498. {
  499. ACBTree *tmp;
  500. NSInteger i;
  501. if (dict.root == nil) return(SUCCESS);
  502. if (t.nodeid == 1) {
  503. srchlvl = 0;
  504. }
  505. else srchlvl++;
  506. for (i = 0; i < t.numkeys; i++) {
  507. tmp = t.btNodes[i];
  508. if (tmp != nil) {
  509. if (tmp.nodeType == LEAF) {
  510. free(tmp); /* free the leaf */
  511. if (tmp == l.rrnode) {
  512. l.rrnode = nil;
  513. }
  514. t.btNodes[i] = nil;
  515. l.chknode.nods_inuse--;
  516. /* putpage(l, l.chknode, 0);
  517. */
  518. }
  519. else {
  520. freetree(l, tmp); /* continue up the tree */
  521. srchlvl--; /* decrement the srchlvl on return */
  522. }
  523. }
  524. }
  525. free(t); /* free the node entered with */
  526. if (t == l.rrnode) {
  527. l.rrnode = nil;
  528. }
  529. l.chknode.nods_inuse--;
  530. /* putpage(l, l.chknode, 0);
  531. */
  532. t = nil;
  533. }
  534. - (void) notfound:(ACBKey *)kp
  535. {
  536. /* error routine to perform if entry was expected and not found */
  537. }
  538. - (void)printtree:(ACBTree *)t
  539. {
  540. BYTE *str;
  541. NSInteger i, j;
  542. NSUInteger *pdate, *ptime;
  543. syslst = stdprn;
  544. if ( t.nodeid == 1 ) {
  545. srchlvl = 0;
  546. }
  547. else srchlvl++;
  548. for (j = 0; j < t.numkeys; j++) {
  549. checknode(l, t, j);
  550. if ( t.btNodes[j] != nil ) [self printtree:t.btNodes[j]];
  551. }
  552. NSLog(@"Nodeid = %d, nodeType = %s, numkeys = %d, numrecs = %d\n",
  553. t.nodeid, (t.nodeType == BTNODE)?@"NODE":@"LEAF", t.numkeys, t.numrecs);
  554. NSLog(@"Left nodeid = %d, Right nodeid = %d\n", t.lnodeid, t.rnodeid);
  555. for (i = 0; i < t.numkeys; i++) {
  556. NSLog(@" t.keys[%d] recnum = %d, keyval = %@",
  557. i, t.keys[i].recnum, t.keys[i]);
  558. str = t.keys[i].kstr;
  559. pdate = (NSUInteger *) (str + 6);
  560. ptime = (NSUInteger *) (str + 8);
  561. NSLog(@" date = %04.4x, time = %04.4x\n",
  562. *pdate, *ptime);
  563. }
  564. }
  565. - (BOOL)puttree:(ACBTree *)t
  566. {
  567. NSInteger i;
  568. if (t.nodeType != LEAF) {
  569. for (i = 0; i < t.numkeys; i++) {
  570. if ( t.btNodes[i] != nil ) puttree(l, t.btNodes[i]);
  571. }
  572. }
  573. if ( t.updtd ) {
  574. putnode(l, t, t.nodeid);
  575. return(YES);
  576. }
  577. return(NO);
  578. }
  579. #endif
  580. /** ROTATELEFT -- rotate keys from right to the left
  581. * starting at position j
  582. */
  583. - (void)rotateleft:(NSInteger)j
  584. {
  585. while ( j+1 < numkeys ) {
  586. keys[j] = keys[j+1];
  587. btNodes[j] = btNodes[j+1];
  588. j++;
  589. }
  590. }
  591. /** ROTATERIGHT -- rotate keys to the right by 1 position
  592. * starting at the last key down to position j.
  593. */
  594. - (void)rotateright:(NSInteger)j
  595. {
  596. NSInteger k;
  597. for ( k = numkeys; k > j; k-- ) {
  598. keys[k] = keys[k-1];
  599. btNodes[k] = btNodes[k-1];
  600. }
  601. keys[j] = nil;
  602. btNodes[j] = nil;
  603. }
  604. - (NSInteger) keyWalkLeaves
  605. {
  606. NSInteger i, idx = 0;
  607. NSInteger keycnt;
  608. ACBTree *t;
  609. if ( self != dict.root ) {
  610. return 0; // maybe I need to throw an exception here
  611. }
  612. t = self;
  613. self.dict.data = [[NSMutableData dataWithLength:(numkeys * sizeof(id))] retain];
  614. self.dict.ptrBuffer = [self.dict.data mutableBytes];
  615. while ( t != nil && t.nodeType != LEAF ) {
  616. t = t.btNodes[0];
  617. }
  618. do {
  619. keycnt = t.numkeys;
  620. for ( i = 0; i < keycnt; i++ ) {
  621. if ( t.btNodes[i] != nil ) {
  622. dict.ptrBuffer[idx++] = (id) t.keys[i].key;
  623. }
  624. }
  625. t = t.rnode;
  626. } while ( t != nil );
  627. return( idx );
  628. }
  629. - (NSInteger) objectWalkLeaves
  630. {
  631. NSInteger i, idx = 0;
  632. NSInteger keycnt;
  633. ACBTree *t;
  634. if ( self != dict.root ) {
  635. return 0; // maybe I need to throw an exception here
  636. }
  637. t = self;
  638. self.dict.data = [[NSMutableData dataWithLength:(numrecs * sizeof(id))] retain];
  639. self.dict.ptrBuffer = [self.dict.data mutableBytes];
  640. while ( t != nil && t.nodeType != LEAF ) {
  641. t = t.btNodes[0];
  642. }
  643. do {
  644. keycnt = t.numkeys;
  645. for ( i = 0; i < keycnt; i++ ) {
  646. if ( t.btNodes[i] != nil ) {
  647. dict.ptrBuffer[idx++] = (id) t.btNodes[i];
  648. }
  649. }
  650. t = t.rnode;
  651. } while ( t != nil );
  652. return( idx );
  653. }
  654. - (void)dealloc
  655. {
  656. #ifdef DEBUG_DEALLOC
  657. NSLog( @"called dealloc in ACBTree" );
  658. #endif
  659. [super dealloc];
  660. }
  661. @end