| … | … | @@ -418,24 +418,42 @@ Handle AtomSpace::getOutgoingAtom(Arity n) const |
| 418 | 418 | } |
| 419 | 419 | |
| 420 | 420 | // ==================================================================== |
| 421 | | // XXX FIXME -- The recursive design of the depth() routine below makes |
| 422 | | // it into a bottleneck, when the stack of AtomSpaces exceeds a few |
| 423 | | // hundred. In particular, the recursion is on the C stack, and I don't |
| 424 | | // believe the compiler has optimized them to be tail-recursive. (If |
| 425 | | // they are tail-recursive, I guess that's OK, eh?) |
| 426 | | // At this time, the only user of this code appears to be UniqueLink.cc |
| 427 | | // It is NOT used by Rocks. |
| 428 | | |
| 421 | /// Search for the given AtomSpace in our stack. Return a count to |
| 422 | /// the shallowest copy found. Return -1 if the AtomSpace is not found |
| 423 | /// in the stack. |
| 424 | // Tail-recursive implementation, should be fast. |
| 429 | 425 | int AtomSpace::depth(const AtomSpace* as) const |
| 430 | 426 | { |
| 431 | 427 | if (nullptr == as) return -1; |
| 432 | 428 | if (as == this) return 0; |
| 433 | 429 | |
| 430 | // As long as _environ is exactly one in size, just loop. |
| 431 | int lvl = 1; |
| 432 | const std::vector<AtomSpacePtr>* env = &_environ; |
| 433 | while (true) |
| 434 | { |
| 435 | size_t evs = env->size(); |
| 436 | if (0 == evs) return -1; |
| 437 | if (1 < evs) break; |
| 438 | if (as == (*env)[0].get()) return lvl; |
| 439 | lvl++; |
| 440 | env = &((*env)[0]->_environ); |
| 441 | } |
| 442 | |
| 443 | // Hunt for shallowest. |
| 444 | int shallowest = -1; |
| 434 | 445 | for (const AtomSpacePtr& base : _environ) |
| 435 | 446 | { |
| 436 | 447 | int d = base->depth(as); |
| 437 | | if (0 <= d) return d+1; |
| 448 | if (0 <= d and |
| 449 | ((-1 == shallowest) or (d < shallowest))) |
| 450 | { |
| 451 | shallowest = d; |
| 452 | } |
| 438 | 453 | } |
| 454 | if (0 <= shallowest) |
| 455 | return lvl + shallowest; |
| 456 | |
| 439 | 457 | return -1; |
| 440 | 458 | } |
| 441 | 459 | |
| … | … | @@ -444,13 +462,7 @@ int AtomSpace::depth(const Handle& atom) const |
| 444 | 462 | if (nullptr == atom) return -1; |
| 445 | 463 | AtomSpace* as = atom->getAtomSpace(); |
| 446 | 464 | if (as == this) return 0; |
| 447 | | |
| 448 | | for (const AtomSpacePtr& base : _environ) |
| 449 | | { |
| 450 | | int d = base->depth(as); |
| 451 | | if (0 <= d) return d+1; |
| 452 | | } |
| 453 | | return -1; |
| 465 | return depth(as); |
| 454 | 466 | } |
| 455 | 467 | |
| 456 | 468 | bool AtomSpace::in_environ(const AtomSpace* as) const |