{"id":32388912,"url":"https://github.com/danlentz/cl-ctrie","last_synced_at":"2026-02-24T19:38:59.042Z","repository":{"id":3906780,"uuid":"4995400","full_name":"danlentz/cl-ctrie","owner":"danlentz","description":"lock-free, concurrent, key/value index with efficient memory-mapped persistence and fast transient storage models","archived":false,"fork":false,"pushed_at":"2015-10-07T19:34:25.000Z","size":4177,"stargazers_count":114,"open_issues_count":3,"forks_count":8,"subscribers_count":17,"default_branch":"master","last_synced_at":"2024-05-09T13:58:14.822Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Common Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/danlentz.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-07-11T21:30:37.000Z","updated_at":"2024-04-19T05:41:11.000Z","dependencies_parsed_at":"2022-09-05T06:11:00.595Z","dependency_job_id":null,"html_url":"https://github.com/danlentz/cl-ctrie","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/danlentz/cl-ctrie","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danlentz%2Fcl-ctrie","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danlentz%2Fcl-ctrie/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danlentz%2Fcl-ctrie/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danlentz%2Fcl-ctrie/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danlentz","download_url":"https://codeload.github.com/danlentz/cl-ctrie/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danlentz%2Fcl-ctrie/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280901443,"owners_count":26410586,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-25T02:00:06.499Z","response_time":81,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-25T03:56:54.795Z","updated_at":"2025-10-25T03:56:56.509Z","avatar_url":"https://github.com/danlentz.png","language":"Common Lisp","readme":"CL-CTRIE\n========\n\n**CL-CTRIE** is a common-lisp implementation of the CTrie unordered map\ndata-structure described in the paper '*Concurrent Tries with\nEfficient Non-Blocking Snapshots*, (c) ACM 2-25-2012' by Prokopec,\nBronson, Bagwell, and Odersky.\n\n### Overview ###\n\nA brief overview of general ctrie\nconcepts and existing implementations is available through its \n[page on wikipedia](http://en.wikipedia.org/wiki/Ctrie), of which the\nfollowing is a brief excerpt:\n\n\u003e The Ctrie data structure is a non-blocking\n\u003e concurrent hash array mapped trie based on\n\u003e single-word compare-and-swap instructions in a\n\u003e shared-memory system. It supports concurrent\n\u003e LOOKUP, INSERT and REMOVE operations. Just like\n\u003e the hash array mapped trie, it uses the entire\n\u003e 32-bit space for hash values thus having low\n\u003e risk of hashcode collisions... Ctries have been\n\u003e shown to be comparable in performance with\n\u003e concurrent skip lists, concurrent hash tables\n\u003e and similar data structures in terms of the\n\u003e lookup operation...  However, they are far more\n\u003e scalable than most concurrent hash tables where\n\u003e the insertions are concerned. Most concurrent\n\u003e hash tables are bad at conserving memory - when\n\u003e the keys are removed from the hash table, the\n\u003e underlying array is not [reduced in size]. Ctries\n\u003e have the property that the allocated memory is\n\u003e always a function of only the current number of\n\u003e keys in the data-structure.  Ctries have logarithmic\n\u003e complexity bounds of the basic operations...\n\u003e with a low constant factor due to [large dispersal\n\u003e ratio, (32^n arcs at level n)]. Ctries support a\n\u003e lock-free, linearizable, constant-time SNAPSHOT\n\u003e operation... This is a breakthrough in concurrent\n\u003e data-structure design, since other existing concurrent\n\u003e data-structures do not support snapshots. [This provides\n\u003e the means to support features such as] lock-free,\n\u003e linearizable iterator, size and clear operations. [This\n\u003e is superior to other] existing concurrent data-structures\n\u003e [which require the use of global locks [for exclusive,\n\u003e blocking semantics for update access] permitting...\n\u003e [no concurrent readers or writers] during any [update,\n\u003e insert, remove or other modifications]. In particular,\n\u003e Ctries have an O(1) ITERATOR creation operation, O(1)\n\u003e CLEAR operation, O(1) DUPLICATE operation and an\n\u003e amortized O(log n) operation for SIZE-RETRIEVAL.\n\n### Platform ###\n\nCurrently the lisp platform supported by cl-ctrie is SBCL version\n1.0.55 or greater hosted on x86/x86-64 architecture. Support could\neasily be entended to include other common-lisp implementations that\noffer atomic compare-and-swap functionality, notably LispWorks\n5.x/6.x, which is also well instrumented with lock-free, atomic\nprimitives, although this is not necessarily a high priority for the\ninitial development cycle.\n\n### Status\n\nAll tests should succeed; parallelism has been tested for 1,\n2, 4, and 8 threads on an 8-core system (Dual Intel(R) Xeon(R) CPU\nE5462 @ 2.80GHz), SBCL version 1.0.57.56-2273f3a, and Mac OS X Server\nversion 10.6.8.\n\n```\nStarting test run on Wednesday, September 5, 2012 09:07:32 AM EDT\n-----------------------------------------------------------------\n\nCHECK-ALET-FSM: 7 assertions passed, 0 failed.\nCHECK-ATOMIC-CLEAR: 6 assertions passed, 0 failed.\nCHECK-ATOMIC-UPDATE: 1 assertions passed, 0 failed.\nCHECK-BULK-INSERT/DROP: 1048579 assertions passed, 0 failed.\nCHECK-BULK-INSERT/LOOKUP: 1048578 assertions passed, 0 failed.\nCHECK-BYTE-VECTOR-HEX-STRING-ROUNDRIP: 10 assertions passed, 0 failed.\nCHECK-CATCH-CASE: 128 assertions passed, 0 failed.\nCHECK-CTRIE-SMOKE-TEST: 31 assertions passed, 0 failed.\nCHECK-DEPTH-AND-SIMPLE-EXTENSION: 8 assertions passed, 0 failed.\nCHECK-EXTENSION/RETRACTION/LNODE-CHAINING: 14 assertions passed, 0 failed.\nCHECK-FBIND: 3 assertions passed, 0 failed.\nCHECK-FLAG-ARC-POSITION: 165 assertions passed, 0 failed.\nCHECK-FLAG-COMPUTATION: 12 assertions passed, 0 failed.\nCHECK-LNODE-INSERTED/REMOVED: 174 assertions passed, 0 failed.\nCHECK-LNODE-LENGTH/ENLIST: 8 assertions passed, 0 failed.\nCHECK-LNODE-SEARCH: 4 assertions passed, 0 failed.\nCHECK-PARALLEL-INSERT-PARALLEL-DROP: 4194316 assertions passed, 0 failed.\nCHECK-PARALLEL-INSERT-PARALLEL-LOOKUP: 4194312 assertions passed, 0 failed.\nCHECK-SIMPLE-INSERT/LOOKUP: 170 assertions passed, 0 failed.\nCHECK-SIMPLE-INSERT/LOOKUP/DROP: 255 assertions passed, 0 failed.\nCHECK-TABLE-ABSTRACTION-FIXTURES: 18 assertions passed, 0 failed.\nCHECK-TIMING-COLLECTION-FIXTURES: 18 assertions passed, 0 failed.\n\nTOTAL: 10,486,817 assertions passed, 0 failed, 0 execution errors.\n```\n\n### Ideosyncrasies\n\nPerhaps most ideosyncrasies of this common-lisp ctrie implementation\nas compared with the [original](http://github.com/axel22/Ctries),\nwritten in Scala, result from the efforts I have taken to, where\nfeasible, adopt an approach emphasizing a more functional oriented\ndecomposition of the algortithm, written in a manner that is more\nclosely representative of ideomatic, common-lisp coding style.  For\nexample, rather than expose a general purpose GCAS and RDCSS api,\nthese protocols are incorporated into ctrie-specific abstractions. For\n__GCAS__ the exposed api includes: `INODE-READ` `INODE-MUTATE` and\n`INODE-COMMIT` and for __RDCSS:__ `ROOT-NODE-ACCESS`\n`ROOT-NODE-REPLACE` and `ROOT-NODE-COMMIT.` The liberties I have taken\nhave the intended benefit of providing an interface that is much\neasier to digest, understand, remember, and work with (at least for\nme) than direct exposure in imperative style of the intricate\nmechanations that underlie the ctrie algorithm.  On the other hand,\nthe further one strays from a direct translation of the original\n(verified) ctrie implementation, the greater the likelihood of\nintroducing bugs into an environment (lock-free concurrent data\nstructure development) in which bugs can be extremely subtle and\nnotoriously difficult to detect.  I have attempted to strike an\nappropriate balance between these conflicting concerns, and I intend\nto mitigate the risk, at least in part, through continued development\nof an extensive arsenal of regression tests and benchmarking\nfacilities.\n\nIn addition, there are a few differences in the feature set that\nis provided -- such as a suite of mapping operators in leiu of a\nJava-style Iterator.  For the most part I expect that these\nchanges will be preferable to developers accustomed to a more\n'lispy' coding style.\n\nFor additional insight into the specifics unique to this ctrie\nimplementation, an abbreviated reference to a number of internal\ndetails may be found in the section [Internal Reference](Internal\nReference) of this document, or, of course, by referring to\nthe [comprehensive documentation](doc/api/index.html) that is\nprovided as part of this distribution.\n\n\n### Source Files\n\nThe following outline provides a general description of the\nconstituent source files of the cl-ctrie repository and their\nrespective purpose.\n\n#### Required\n\nThe following files are the core sources currently necessary\nfor correct ctrie operation. \n\n- __`ctrie-package.lisp:`__  Package Definition\n- __`ctrie.lisp:`__          Structural Implementation\n- __`ctrie-util.lisp:`__     Supporting Utilities\n\n#### Supplemental\n\nThe following files define extended functionality, management,\nand analysis facilities supporting the development of CL-CTRIE.\n\n- `ctrie-cas.lisp:`   SBCL CAS extensions\n- `ctrie-lambda.lisp:` Experiments with Stateful Protocols\n- `ctrie-doc.lisp:`   Automated Documentation Support\n- `ctrie-test.lisp:`  Test and Performance Measurement\n\n### Performance\n\nTo date, the principal concern has been to fully achieve a working\nand robust implementation of the CTRIE algorithm, with only the\noccaisional profiling run from time to time in order to at least\nget a general sense of where the hot-spots are and peace of mind\nthat there are at least no glaring bottlenecks that seem out of\nhand.  A basic profiling exercise of the following activities is\nreported below.\n\n    1. construct a new ctrie instance\n    2. perform one-million insertions of (fixnum) key/value pairs\n    3. perform one-million lookups verifying retrieval of every value\n    4. perform one-million removals verifying proper contraction of the structure\n    5. verify the resulting ctrie is identical to when initially created.\n\n    \n```\n  seconds  |     gc     |    consed   |    calls   |  sec/call  |  name  \n--------------------------------------------------------------\n     1.331 |      1.001 | 332,691,664 |  2,198,622 |   0.000001 | MAKE-CNODE\n     1.123 |      0.000 |       1,904 |  3,179,578 |   0.000000 | CTHASH\n     0.871 |      0.000 |      44,608 |  5,344,350 |   0.000000 | ROOT-NODE-ACCESS\n     0.847 |      0.182 |  69,549,200 |  2,198,622 |   0.000000 | %MAKE-CNODE\n     0.820 |      0.000 |         576 | 12,582,934 |   0.000000 | FLAG\n     0.796 |      0.000 |         352 | 12,582,934 |   0.000000 | FLAG-ARC-POSITION\n     0.611 |      0.000 |         832 |  2,130,976 |   0.000000 | CTEQUAL\n     0.551 |      0.000 |      33,600 | 12,549,110 |   0.000000 | FLAG-PRESENT-P\n     0.529 |      0.000 |         720 |  5,344,350 |   0.000000 | FIND-CTRIE-ROOT\n     0.496 |      0.044 | 108,904,336 |  2,198,622 |   0.000000 | MAKE-REF\n     0.295 |      0.102 |  33,284,592 |  1,048,576 |   0.000000 | MAKE-SNODE\n     0.243 |      0.000 |         144 |  2,198,622 |   0.000000 | CTSTAMP\n     0.225 |      0.000 |         256 |  2,097,152 |   0.000000 | LEAF-NODE-KEY\n     0.216 |      0.118 |  32,803,552 |  1,048,576 |   0.000000 | CNODE-EXTENDED\n     0.189 |      0.000 |      32,848 |  2,097,152 |   0.000000 | LEAF-NODE-VALUE\n     0.146 |      0.000 |       1,872 |  1,048,576 |   0.000000 | SNODE\n     0.018 |      0.000 |           0 |     33,824 |   0.000001 | MAKE-INODE\n     0.016 |      0.000 |           0 |     34,257 |   0.000000 | RESURRECT\n     0.007 |      0.000 |   1,048,304 |     33,824 |   0.000000 | MAKE-TNODE\n     0.000 |      0.127 |  50,427,456 |  1,048,576 |   0.000000 | CTRIE-GET\n     0.000 |      0.000 |           0 |          1 |   0.000000 | CTRIE-SIZE\n     0.000 |      0.000 |       5,104 |  1,048,576 |   0.000000 | CTRIE-PUT\n     0.000 |      0.000 |           0 |          1 |   0.000000 | CTRIE-EMPTY-P\n     0.000 |      0.000 |           0 |          1 |   0.000000 | CTRIE-MAP\n     0.000 |      0.000 |      42,544 |  1,048,602 |   0.000000 | CTRIE-DROP\n     0.000 |      0.000 |           0 |          1 |   0.000000 | CTRIE-MAP-KEYS\n     0.000 |      0.000 |           0 |  1,116,226 |   0.000000 | MAP-NODE\n     0.000 |      0.000 |           0 |     33,824 |   0.000000 | ENTOMB\n     0.000 |      0.000 |           0 |     67,620 |   0.000000 | CNODE-UPDATED\n     0.000 |      0.000 |     268,496 |  4,160,480 |   0.000000 | %INSERT\n     0.000 |      0.000 |      39,024 |  2,164,798 |   0.000000 | INODE-COMMIT\n     0.000 |      0.000 |     342,688 |  4,160,556 |   0.000000 | %REMOVE\n     0.000 |      0.000 |         544 |     33,796 |   0.000000 | CLEAN-PARENT\n     0.000 |      0.000 |   1,375,952 |     33,824 |   0.000000 | %MAKE-INODE\n     0.000 |      0.000 |     262,352 |  4,194,304 |   0.000000 | %LOOKUP\n     0.000 |      0.000 |       3,504 |  1,048,576 |   0.000000 | CNODE-TRUNCATED\n     0.000 |      0.000 |           0 |         26 |   0.000000 | MAP-CNODE\n--------------------------------------------------------------\n     9.328 |      1.574 | 631,167,024 | 90,110,445 |            | Total\n```\n\n### Documentation\n\nComprehensive, HTML based [documentation](doc/api/index.html) may be\nfound at the project relative pathname `doc/api/index.html`.  In order\nto enable support for supplemental documentation related features, such\nas the ability to dynamically regenerate the provided documentation\nfiles incorporating all updates and changes as may be present in the\nsource code, a (lightly) enhanced distribution of CLDOC is required\nand may be obtained on [github](http://github.com/danlentz/cldoc).\n\nThe following sections provide a compact overview of the user api\nand a reference to some internal definitions of interest.\n\n#### User API Reference\n\nThe user api of cl-ctrie should be largely familiar to the average\ncommon-lisp programmer.  Nearly all exported symbols of the CL-CTRIE \npackage begin with the prefix \"ctrie\" and thus can be convenientely\nincorporated via USE-PACKAGE or equivalent package definition.  The\nfollowing definitions comprise a quick reference to the the public\nuser api:\n\n* * * * * *\n\n\n_[structure]_        `CTRIE ()`\n\n\u003e A CTRIE structure is the root container that uniquely identifies a CTRIE\n  instance, and  contains the following perameters which specify the\n  definable aspects of each CTRIE:\n\n  - `READONLY-P` if not `NIL` prohibits any future modification or\n  cloning of this instance.\n  - `TEST` is a designator for an equality predicate that will be\n  applied to disambiguate and determine the equality of any two\n  keys. It is recommened that this value be a symbol that is fboundp,\n  to retain capability of externalization (save/restore). At present,\n  though, this is not enforced and a function object or lambda\n  expression will also be accepted, albeit without the ability of\n  save/restore.\n  - `HASH` is a designator for a hash function, which may be\n  desirable to customize when one has specific knowledge about the set\n  of keys which will populate the table.  At this time, a 32-bit hash\n  is recommended as this is what has been used for development and\n  testing and has been shown to provide good performance in\n  practice. As with `TEST` it is recommended that `HASH` be specified\n  by a symbol that is fboundp.\n  - `ROOT` is the slot used internally for storage of the root inode\n  structure that maintains the reference to the contents of the ctrie\n  proper.  The ctrie-root must only be accessed using the _RDCSS ROOT\n  NODE PROTOCOL_ defined by the top-level entry-points `ROOT-NODE-ACCESS`\n  and `ROOT-NODE-REPLACE`\n\n\n_[function]_         `MAKE-CTRIE  (\u0026REST ARGS \u0026KEY NAME ROOT (READONLY-P NIL)\n                                   (TEST 'EQUAL) (HASH 'SXHASH)\n                                   \u0026ALLOW-OTHER-KEYS)`\n\n\u003e CREATE a new CTRIE instance. This is the entry-point constructor \n  intended for use by the end-user.\n\n\n_[function]_         `CTRIE-P  (OBJECT)`\n\n\u003e Returns T if the specified object is of type ctrie.\n\n\n_[function]_         `CTRIE-TEST  (CTRIE)`\n\n\u003e Returns the test of the specified ctrie\n\n\n\n_[function]_         `CTRIE-HASH  (CTRIE)`\n\n\u003e Returns the hash of the specified ctrie\n\n\n\n_[function]_         `CTRIE-READONLY-P  (CTRIE)`\n\n\u003e Returns and (with setf) changes the readonly-p of the specified ctrie\n\n\n\n_[function]_         `CTRIE-PUT  (CTRIE KEY VALUE)`\n\n\u003e Insert a new entry into CTRIE mapping KEY to VALUE.  If an entry\n  with key equal to KEY aleady exists in CTRIE, according to the\n  equality predicate defined by `CTRIE-TEST` then the priorbmapping\n  will be replaced by VALUE. Returns `VALUE` representing the\n  mapping in the resulting CTRIE\n\n\n_[function]_         `CTRIE-GET  (CTRIE KEY)`\n\n\u003e Find the entry in CTRIE whose key is KEY and returns the\n  associated value and T as multiple values, or returns NIL and NIL\n  if there is no such entry. Entries can be added using SETF.\n\n\n_[function]_         `CTRIE-DROP  (CTRIE KEY)`\n\n\u003e Remove KEY and it's associated value from CTRIE. Returns as multiple\n  values the value associated with KEY and T if there was such an entry,\n  otherewise NIL and NIL\n\n\n_[macro]_            `CTRIE-DO  ((KEY VALUE CTRIE \u0026KEY ATOMIC) \u0026BODY BODY)`\n\n\u003e Iterate over the contents of CTRIE in the manner of dolist. For each\n  (key . value) pair present in CTRIE, BODY (implicit PROGN) will be\n  evaluated with the symbols specified for KEY and VALUE will be bound\n  to the respective entry constituents.  A special variable\n  ACCUM (initially NIL) is available for accumulation of a result\n  value which will be returned after the completion of the CTRIE-DO\n  call.  If ATOMIC is non-NIL, the operation will be performed on a\n  read-only atomic snapshot of CTRIE, which guarantees a consistent,\n  point-in-time representation of the entries present in CTRIE.\n  ```\n  ;;;  EXAMPLE: (ctrie-do (k v ctrie)\n  ;;;             (format t \"~\u0026~8S =\u003e ~10S~%\" k v))\n  ```\n\n\n_[function]_         `CTRIE-MAP  (CTRIE FN \u0026KEY ATOMIC \u0026AUX ACCUM)`\n\n\u003e Applies a function two arguments, FN, to each (key . value) pair present in\n  CTRIE.  During the extent of CTRIE-MAP, a special variable ACCUM (initially NIL)\n  is available for accumulation of a result value which will be returned after\n  the completion of the CTRIE-MAP call.  If ATOMIC is non-NIL, the operation will\n  be performed on a read-only atomic snapshot of CTRIE, which guarantees a\n  consistent, point-in-time representation of the entries present in CTRIE\n\n\n_[function]_         `CTRIE-MAP-KEYS  (CTRIE FN \u0026KEY ATOMIC)`\n\n\u003e Applies a function one argument, FN, to each key present in CTRIE.\n  During the extent of CTRIE-MAP-KEYS, a special variable\n  ACCUM (initially NIL) is available for accumulation of a result\n  value which will be returned after the completion of the\n  CTRIE-MAP-KEYS call.  If ATOMIC is non-NIL, the operation will be\n  performed on a read-only atomic snapshot of CTRIE, which guarantees\n  a consistent, point-in-time representation of the keys present in\n  CTRIE\n\n\n_[function]_         `CTRIE-MAP-VALUES  (CTRIE FN \u0026KEY ATOMIC)`\n\n\u003e Applies a function one argument, FN, to each value present in CTRIE.\n  During the extent of CTRIE-MAP-VALUES, a special variable\n  ACCUM (initially NIL) is available for accumulation of a result\n  value which will be returned after the completion of the\n  CTRIE-MAP-VALUES call.  If ATOMIC is non-NIL, the operation will be\n  performed on a read-only atomic snapshot of CTRIE, which guarantees\n  a consistent, point-in-time representation of the values present in\n  CTRIE\n\n\n_[function]_         `CTRIE-KEYS  (CTRIE \u0026KEY ATOMIC)`\n\n\u003e Construct and return a list containing all keys present in CTRIE.\n  If ATOMIC is non-NIL, the operation will be performed on a read-only\n  atomic snapshot of CTRIE, which guarantees a consistent,\n  point-in-time representation of the keys present in CTRIE\n\n\n_[function]_         `CTRIE-VALUES  (CTRIE \u0026KEY ATOMIC)`\n\n\u003e Construct and return a list containing all values present in CTRIE.\n  If ATOMIC is non-NIL, the operation will be performed on a read-only\n  atomic snapshot of CTRIE, which guarantees a consistent,\n  point-in-time representation of the values present in CTRIE\n\n\n_[function]_         `CTRIE-SIZE  (CTRIE \u0026KEY ATOMIC \u0026AUX (ACCUM 0))`\n\n\u003e Return the number of entries present in CTRIE.  If ATOMIC is non-NIL,\n  the operation will be performed on a read-only atomic snapshot of CTRIE,\n  which guarantees a consistent, point-in-time representation of CTRIE\n\n\n_[function]_         `CTRIE-CLEAR  (CTRIE)`\n\n\u003e Atomically clear all entries stored in CTRIE, returning it to a condition\n  which returns `T` when tested with predicate `CTRIE-EMPTY-P`\n\n\n_[function]_         `CTRIE-PPRINT  (CTRIE \u0026OPTIONAL (STREAM T))`\n\n\u003e Pretty-print a representation of CTRIE as an alist containing\n  all (key . value) pairs found in it.  Atomicity is not guaranteed\n\n\n_[function]_         `CTRIE-TO-ALIST  (CTRIE \u0026KEY ATOMIC)`\n\n\u003e Return an alist containing all (key . value) pairs found in CTRIE.\n  If ATOMIC is non-NIL, the operation will be performed on a read-only\n  atomic snapshot of CTRIE, which guarantees a consistent,\n  point-in-time representation of the entries in CTRIE\n\n\n_[function]_         `CTRIE-TO-HASHTABLE  (CTRIE \u0026KEY ATOMIC HASH-TABLE \u0026AUX\n                                           (ACCUM\n                                            (OR HASH-TABLE\n                                                (MAKE-HASH-TABLE :TEST\n                                                                 (CTRIE-TEST\n                                                                  CTRIE)\n                                                                 :HASH-FUNCTION\n                                                                 (CTRIE-HASH\n                                                                  CTRIE)\n                                                                 :SYNCHRONIZED\n                                                                 ATOMIC))))`\n\n\u003e Return a hash-table containing all (key . value) pairs found in CTRIE.\n  If ATOMIC is non-NIL, the operation will be performed on a read-only\n  atomic snapshot of CTRIE, which guarantees a consistent,\n  point-in-time representation of the entries in CTRIE. If HASH-TABLE\n  is specified, it will be used as the destination hash-table.\n  Otherwise, a new hash-table will be created with hash-function and\n  test identical to that of CTRIE.  It will be created as synchronized\n  if ATOMIC is not NIL\n\n\n_[function]_         `CTRIE-FROM-HASHTABLE  (HASH-TABLE \u0026KEY CTRIE)`\n\n\u003e Return a CTRIE containing all (key . value) pairs found in HASH-TABLE.\n  If CTRIE is specified, it will be used as the destination ctrie.\n  Otherwise, a new ctrie will be created with test identical to that\n  of HASH-TABLE. The hash-function will NOT be preserved, as that\n  information does not appear to be recoverable from a hash-table once\n  created\n\n\n_[function]_         `CTRIE-FROM-ALIST  (ALIST \u0026KEY CTRIE)`\n\n\u003e Return a CTRIE containing all (key . value) pairs found in ALIST.\n  If CTRIE is specified, it will be used as the destination ctrie.\n  Otherwise, a new ctrie will be created. Atomicity is not guaranteed\n\n\n_[function]_         `CTRIE-EMPTY-P  (CTRIE)`\n\n\u003e Return T if CTRIE contains no entries, otherwise NIL. This function is\n  O(1) and is much more efficient than testing for `CTRIE-SIZE` of 0\n\n\n_[function]_         `CTRIE-MAX-DEPTH  (THING)`\n\n\u003e Compute the maximum length of any arc. Useful as a diagnostic\n\n\n_[function]_         `CTRIE-MIN-DEPTH  (THING)`\n\n\u003e Compute the minimum length of any arc. Useful as a diagnostic\n\n\n_[function]_         `CTRIE-SNAPSHOT  (CTRIE \u0026KEY READ-ONLY)`\n\n\u003e Atomically create a clone of CTRIE that may be operated upon\n  independently without affecting or being affected by operations or\n  content of the original CTRIE.  If READ-ONLY is NIL (the default),\n  the new CTRIE will be a READABLE/WRITABLE 'fork' of CTRIE (see\n  `CTRIE-FORK`) otherwise, the clone will be READABLE only, which has\n  considerable performance benefits in some circumstances, as the arcs\n  will not require `REFRESH` and should be the preferred mode when\n  updates (writability) of the clone are not required\n\n\n_[function]_         `CTRIE-FORK  (CTRIE)`\n\n\u003e Atomically create a READABLE and WRITABLE clone of CTRIE that may\n  be operated upon independently without affecting or being affected\n  by the original CTRIE.\n\n\n_[macro]_            `CTRIE-LAMBDA  (\u0026ONCE CTRIE \u0026REST REST)`\n\n\u003e Pandoric Object and Inter-Lexical Communication Protocol\n  this macro builds the most unencumbered and widely applicable\n  'purist edition' Of our PLAMBDA based form.  Even as such,\n  a lot of care has been given to many subtle ways it has been\n  refined to offer the most convenient and natural tool possible.\n  ```;;;\n     ;;; (plambda (#\u003cCLOSURE (LAMBDA (\u0026REST ARGS)) {100929EB1B}\u003e )\n     ;;;\n     ;;; DISPATCHING to FUNCTIONAL MAPPING:\n     ;;;   (IF (REST ARGS)\n     ;;;          (APPLY ARG (REST ARGS))\n     ;;;          (FUNCALL ARG #'IDENTITY)) =\u003e\n     ;;; ------------------------------------------------------------\n     ;;; INITIALIZING PLAMBDA\n     ;;; ------------------------------------------------------------\n     ;;;   IT =\u003e #S(CTRIE\n     ;;;               :READONLY-P NIL\n     ;;;               :TEST EQUAL\n     ;;;               :HASH SXHASH\n     ;;;               :STAMP #\u003cCLOSURE (LAMBDA # :IN CONSTANTLY) {10092B516B}\u003e\n     ;;;               :ROOT #S(INODE\n     ;;;                        :GEN #:|ctrie2196|\n     ;;;                        :REF #S(REF\n     ;;;                                :STAMP @2012-08-19T13:34:58.314457-04:00\n     ;;;                                :VALUE #S(CNODE :BITMAP 0 :ARCS #())\n     ;;;                                :PREV NIL)))\n     ;;;   PLIST =\u003e (:CONTAINER #\u003cCLOSURE (LAMBDA #) {100929EACB}\u003e \n     ;;;             :TIMESTAMP @2012-08-19T13:34:58.314464-04:00)\n     ;;;   STACK =\u003e (#\u003cCLOSURE (LAMBDA #) {100929EACB}\u003e)\n     ;;; \n     ;;; ------------------------------------------------------------\n     ;;;  #\u003cCLOSURE (LAMBDA (\u0026REST #:ARGS55)) {100929EACB}\u003e\n     ;;;```\n\n\n_[generic-function]_ `CTRIE-LAMBDA-CTRIE  (CTRIE-LAMBDA-OBJECT)`\n\n\u003e Returns and (with setf) changes the ctrie of the specified ctrie-lambda-object\n\n\n\n_[function]_         `CTRIE-LAMBDA-SPAWN  (SELF \u0026KEY READ-ONLY)`\n\n\u003e Causes the atomic clone of enclosed ctrie structure and builds a new\n  lexical closure to operate on it.  Does not bother to reproduce fancy\n  (expensive) object, class, bindings, but provides almost identical\n  functionality.  May be used to more efficintly distribute workload\n  in parallel\n\n\n_[macro]_            `DEFINE-CTRIE  (NAME CTRIE \u0026REST ARGS \u0026KEY (OBJECT T) SPEC)`\n\n\u003e Define a 'functional' __CTRIE-LAMBDA__ that combines all the the\n  capabilities of the raw data structure with behavior and semantics\n  one would expect of any other ordinary common-lisp function.  The\n  resulting symbol defined as 'name will be bound in three distinct\n  namespaces: the `SYMBOL-VALUE` will be bound to the LAMBDA CLOSURE\n  object, `SYMBOL-FUNCTION` (fdefinition) will be FBOUND to the\n  compiled function, and the corresponding '(SETF NAME) form will be\n  SETF-BOUND.  the syntax for invoking NAME is as in a LISP1; i.e., no\n  'funcall' is required (but still works if you prefer).\n  Calling `(NAME key)` returns the value mapped to key, or `NIL` just\n  as if by `(CTRIE-GET ctrie-name key).` Analogously when used as a\n  setf-able place such as by `(setf (NAME key) value)` it has the\n  equivalent behavior to the operation `(CTRIE-PUT ctrie-name key\n  value).` Use of this type of binding technique has some really\n  convenient effects that I've quickly started to become quite fond\n  of.  One such idiom, for example, `(mapcar MY-CTRIE '(key1 key2 key3\n  key4 ...))` returns a list containing all the mapped values\n  corresponding to the respective keys.  One additional feature that\n  I've found extremely useful is included _under the hood:_ Invoking\n  MY-CTRIE on an object of type FUNCTION will not search the ctrie for\n  an entry having that function ast its key, but will instead APPLY\n  that function to the actual CTRIE structure wrapped within the\n  closure.  Thus, `(MY-CTRIE #'identity)` will return the underlying\n  ctrie as just an ordinary instance of a CTRIE STRUCTURE.  \n  There are many other functions this is handy with, like\n  `(MY-CTRIE #'ctrie-size)` `(MY-CTRIE #'ctrie-to-hashtable)`\n  etc.  Some additional examples are provided below.\n  ```\n  ;;;  (define-ctrie my-ctrie)\n  ;;;    =\u003e  MY-CTRIE\n  ;;;\n  ;;;  (describe 'my-ctrie)\n  ;;;\n  ;;;     CL-CTRIE::MY-CTRIE\n  ;;;       [symbol]\n  ;;;    \n  ;;;     MY-CTRIE names a special variable:\n  ;;;       Value: #\u003cCLOSURE (LAMBDA # :IN MAKE-CTRIE-LAMBDA) {100F73261B}\u003e\n  ;;;    \n  ;;;     MY-CTRIE names a compiled function:\n  ;;;       Lambda-list: (\u0026REST ARGS1)\n  ;;;       Derived type: FUNCTION\n  ;;;    \n  ;;;     (SETF MY-CTRIE) names a compiled function:\n  ;;;       Lambda-list: (VALUE KEY)\n  ;;;       Derived type: (FUNCTION (T T) *)\n  ;;;\n  ;;;\n  ;;;   (my-ctrie :HONG-KONG :FOOY)\n  ;;;     =\u003e  :FOOY\n  ;;;\n  ;;;   (my-ctrie :HONG-KONG)\n  ;;;     =\u003e  :FOOY ; T\n  ;;;\n  ;;;   (map 'list #'eval (mapcar #`(my-ctrie ,a1 ,a1) (iota 12)))\n  ;;;     =\u003e  (0 1 2 3 4 5 6 7 8 9 10 11)\n  ;;;\n  ;;;   (mapcar my-ctrie (iota 12))\n  ;;;     =\u003e  (0 1 2 3 4 5 6 7 8 9 10 11)\n  ```\n\n\n_[macro]_            `CTRIE-ERROR  (CONDITION \u0026REST ARGS)`\n\n\u003e Signal a CTRIE related condition.\n\n\n_[condition]_        `CTRIE-ERROR (ERROR)`\n\n\u003e Abstract superclass of CTRIE related conditions.\n\n\n_[condition]_        `CTRIE-STRUCTURAL-ERROR (CTRIE-ERROR)`\n\n\u003e Condition designating that the CTRIE data structure\n   has been determined to be invalid.\n\n\n_[condition]_        `CTRIE-OPERATIONAL-ERROR (CTRIE-ERROR)`\n\n\u003e Condition for when an operational failure or\n  inconsistency has occurred.\n\n\n_[condition]_        `CTRIE-OPERATION-RETRIES-EXCEEDED (CTRIE-OPERATIONAL-ERROR)`\n\n\u003e Condition indicating an operation has failed the\n   maximum number of times specified by the special-variable\n   *retries*\n\n\n_[condition]_        `CTRIE-NOT-IMPLEMENTED (CTRIE-ERROR)`\n\n\u003e Condition designating functionality for which the\n   implementation has not been written, but has not been deliberately\n   excluded.\n\n\n_[condition]_        `CTRIE-NOT-SUPPORTED (CTRIE-ERROR)`\n\n\u003e Condition designating functionality that is\n  deliberately not supported.\n\n\n_[condition]_        `CTRIE-INVALID-DYNAMIC-CONTEXT (CTRIE-OPERATIONAL-ERROR)`\n\n\u003e Condition indicating an operation was attempted\n   outside the dynamic extent of a valid enclosing WITH-CTRIE form\n\n\n_[condition]_        `CTRIE-GENERATIONAL-MISMATCH (CTRIE-STRUCTURAL-ERROR)`\n\n\u003e Condition indicating an operation encountered an\n   outdated or inconsistent node during its attempted traversal\n\n\n_[function]_         `CTRIE-MODIFICATION-FAILED  (REASON \u0026KEY OP PLACE)`\n\n\u003e Signal a modification failure with the appropriate attendant metadata.\n\n\n_[condition]_        `CTRIE-MODIFICATION-FAILED (CTRIE-OPERATIONAL-ERROR)`\n\n\u003e This condition indicates an unhandled failure of an attempt to\n         perform stateful modification to CTRIE.  The most common case in\n         which this might occur is when such an attempt is mode on a CTRIE\n         designated as READONLY-P.  In any case, this condition represents an\n         exception from which processing cannot continue and requires\n         interactive user intervention in order to recover.\n\n\n* * * * * *\n\n#### Internal Reference (abridged)\n\nThe following reference describes some selected internal\nimplementation details of interest.  Under normal circumstances it\nshould not be necessary to interact with these unexported symbols\nunless developing an extension to cl-ctrie, but are presented here for\nthe sake of convenience, in order to provide better insight into the ctrie\nstructure in general, and to help illuminate significant aspects of this\nimplementation in particular.  As mentioned above, [comprehensive\ndocumentation](doc/api/index.html) of all symbols is also provided,\nand should be considered the authoratative reference to the CL-CTRIE\nimplementation.\n\n* * * * * * *\n\n\n_[special-variable]_ `*CTRIE*  (NIL)`\n\n\u003e Within the dynamic extent of a CTRIE operation this variable will\n  be bound to the root-container CTRIE operand.  It is an error if an\n  operation is defined that attempts access to a CTRIE without this\n  binding, which is properly established by wrapping the operation in\n  an appropriate WITH-CTRIE form.\n\n\n_[special-variable]_ `*RETRIES*  (16)`\n\n\u003e Establishes the number of restarts permitted to a CTRIE operation\n  established by a WITH-CTRIE form before a condition of type\n  CTRIE-OPERATION-RETRIES-EXCEEDED will be signaled, aborting the\n  operatation, and requiring operator intervention to resume\n  processing.\n\n\n_[special-variable]_ `*TIMEOUT*  (2)`\n\n\u003e Establishes the duration (in seconds) allotted to a CTRIE operation\n  established by a WITH-CTRIE form before a condition of type\n  CTRIE-OPERATION-TIMEOUT-EXCEEDED will be signaled, aborting the\n  operatation, and requiring operator intervention to resume\n  processing.\n\n\n_[special-variable]_ `*HASH-CODE*  (NIL)`\n\n\u003e Special variable used to store the hash-code that corresponds to the\n  current operation.  Used as a means of improving efficiency by eliminating\n  needless recomputation of the hash function, which is the most expensive\n  part of most user-level ctrie operations.  If this value is not set, then\n  the hash will simply be computed on demand and processing will continue\n  unaffected.  Use of this variable is simply an optional performace\n  optimization techniqie.\n\n\n_[macro]_            `MULTI-CATCH  (TAG-LIST \u0026BODY FORMS)`\n\n\u003e Macro allowing catch of multiple tags at once and\n    finding out which tag was thrown.\n    * RETURNS: (values RESULT TAG)\n       -  RESULT is either the result of evaluationg FORMS or the value\n          thrown by the throw form.\n       -  TAG is NIl if evaluation of the FORMS completed normally\n          or the tag thrown and cought.\n    * EXAMPLE:\n    ```\n        ;;; (multiple-value-bind (result tag)\n        ;;;            (multi-catch (:a :b)\n        ;;;                 ...FORMS...)\n        ;;;              (case tag \n        ;;;                 (:a ...)\n        ;;;                 (:b ...)\n        ;;;                 (t ...)))\n    ```\n\n\n_[macro]_            `CATCH-CASE  (FORM \u0026REST CASES)`\n\n\u003e User api encapsulating the MULTI-CATCH control-structure in a\n    syntactic format that is identical to that of the familiar CASE\n    statement, with the addition that within the scope of each CASE\n    clause, a lexical binding is established between the symbol IT and\n    the value caught from the throw form.\n\n\n_[structure]_        `CTRIE ()`\n\n\u003e A CTRIE structure is the root container that uniquely identifies a CTRIE\n  instance, and  contains the following perameters which specify the\n  definable aspects of each CTRIE:\n\n  - `READONLY-P` if not `NIL` prohibits any future modification or\n  cloning of this instance.\n  - `TEST` is a designator for an equality predicate that will be\n  applied to disambiguate and determine the equality of any two\n  keys. It is recommened that this value be a symbol that is fboundp,\n  to retain capability of externalization (save/restore). At present,\n  though, this is not enforced and a function object or lambda\n  expression will also be accepted, albeit without the ability of\n  save/restore.\n  - `HASH` is a designator for a hash function, which may be\n  desirable to customize when one has specific knowledge about the set\n  of keys which will populate the table.  At this time, a 32-bit hash\n  is recommended as this is what has been used for development and\n  testing and has been shown to provide good performance in\n  practice. As with `TEST` it is recommended that `HASH` be specified\n  by a symbol that is fboundp.\n  - `ROOT` is the slot used internally for storage of the root inode\n  structure that maintains the reference to the contents of the ctrie\n  proper.  The ctrie-root must only be accessed using the _RDCSS ROOT\n  NODE PROTOCOL_ defined by the top-level entry-points `ROOT-NODE-ACCESS`\n  and `ROOT-NODE-REPLACE`\n\n\n_[function]_         `CTRIE-P  (OBJECT)`\n\n\u003e Returns T if the specified object is of type ctrie.\n\n\n_[function]_         `CTRIE-HASH  (CTRIE)`\n\n\u003e Returns the hash of the specified ctrie\n\n\n\n_[function]_         `CTRIE-TEST  (CTRIE)`\n\n\u003e Returns the test of the specified ctrie\n\n\n\n_[function]_         `CTRIE-READONLY-P  (CTRIE)`\n\n\u003e Returns and (with setf) changes the readonly-p of the specified ctrie\n\n\n\n_[function]_         `CTHASH  (KEY)`\n\n\u003e Compute the hash value of KEY using the hash function defined by\n  the CTRIE designated by the innermost enclosing WITH-CTRIE form.\n\n\n_[function]_         `CTEQUAL  (X Y)`\n\n\u003e Test the equality of X and Y using the equality predicate defined\n  by the CTRIE designated by the innermost enclosing WITH-CTRIE form.\n\n\n_[macro]_            `WITH-CTRIE  (\u0026ONCE CTRIE \u0026BODY BODY)`\n\n\u003e Configure the dynamic environment with the appropriate condition\n  handlers, control fixtures, and instrumentation necessary to execute\n  the operations in BODY on the specified CTRIE. Unless specifically\n  documented, the particular configuration of this dynamic environment\n  should be considered an implementation detail and not relied upon. A\n  particular exception, however, is that within the dynamic extent of\n  a WITH-CTRIE form, the code implementing a CTRIE operation may\n  expect that the special variable `*CTRIE*` will be bound to the root\n  container of subject CTRIE.  See also the documentation for\n  `*CTRIE*`\n\n\n_[function]_         `FLAG  (KEY LEVEL \u0026OPTIONAL USE-CACHED-P)`\n\n\u003e For a given depth, LEVEL, within a CTRIE, extract the correspondant\n  sequence of bits from the computed hash of KEY that indicate the\n  logical index of the arc on the path to which that key may be found.\n  If USE-CACHED-P is non-NIL and the special-variable `*HASH-CODE*` is\n  non-NIL as well, the hash will not be recomputed, but instead the\n  value bound to `*HASH-CODE*` will be used as an optimization to\n  reduce unnecessary recomputation of hash function -- an expensive\n  operation.  This value is NOT checked and assumed to be valid and\n  appropriate to the given situation -- care must be taken to use this\n  cached value correctly.  When in doubt, recomputing hash may be a\n  performance penalty, but is guaranteed to always work in any\n  situation.  Note that the logical index of the arc is most likely\n  not the same as the physical index where it is actually located --\n  for that see `FLAG-ARC-POSITION`\n\n\n_[function]_         `FLAG-PRESENT-P  (FLAG BITMAP)`\n\n\u003e Tests the (fixnum) BITMAP representing the logical index of all\n  arcs present in a CNODE for the presence of a particular arc whose\n  logical index is represented by FLAG.\n\n\n_[function]_         `FLAG-ARC-POSITION  (FLAG BITMAP)`\n\n\u003e Given FLAG representing the logical index of an arc, and BITMAP\n  representing all arcs present, compute a physical index for FLAG in\n  such a manner as to always ensure all arcs map uniquely and\n  contiguously to the smallest vector that can contain the given\n  arcs.\n\n\n_[function]_         `FLAG-VECTOR  (\u0026OPTIONAL (CONTENT 0))`\n\n\u003e FLAG-VECTOR is a bit-vector representation of the (fixnum)\n  BITMAP. It is currently not used for any calculation, however it is\n  included within each CNODE as a convenience because it makes it\n  immediately clear from visual inspection which logical arc indexes\n  are represented in the node. For example, from the bit-vector\n  `#*10010000000000000000000000000000` one can easily see that the first\n  and fourth positions are occupied, and the rest empty.\n\n\n_[structure]_        `REF ()`\n\n\u003e Atomically Stamped Reference structure _[Herlithy, TAOMP]_ that\n  encapsulates the mutable slots within an inode. Any specific `REF`\n  structure is, itself, never mutated.  Using the `REF` structure\n  as basis of inode implementation provides the capability to 'bundle'\n  additional metadata in an inode while still providing atomic compare\n  and swap using a single comparison of the aggregate `REF` instance.\n   - `STAMP` defines a slot containing implementation-specific metadata\n     that may be maintained internally as a means of tracking inode\n     modification and update behavior.  It should not be referenced by\n     user code, and the format of its contents should not be relied apon.\n   - `VALUE` defines a slot that contains a reference to the MAIN-NODE\n     that the enclosing inode should be interpreted as 'pointing to'\n   - `PREV` defines a slot which, during the `INODE-COMMIT` phase of the\n     _GCAS INODE PROTOCOL_ maintains a reference to the last valid\n     inode state, which may be restored, if necessary, during the\n     course of the `INODE-READ` / `INODE-COMMIT` arbitration process\n\n\n_[function]_         `REF-P  (OBJECT)`\n\n\u003e Returns T if the specified object is of type ref.\n\n\n_[function]_         `REF-STAMP  (REF)`\n\n\u003e Returns the stamp of the specified ref\n\n\n\n_[function]_         `REF-VALUE  (REF)`\n\n\u003e Returns the value of the specified ref\n\n\n\n_[function]_         `REF-PREV  (REF)`\n\n\u003e Returns and (with setf) changes the prev of the specified ref\n\n\n\n_[structure]_        `FAILED-REF (REF)`\n\n\u003e A `FAILED-REF` is a structure that is used to preserve the linkage to\n  prior inode state following a failed GCAS.  Any inode access that\n  detects a `FAILED-REF` will immediately invoke a commit to restore the\n  inode to the state recorded in `FAILED-REF-PREV`\n\n\n_[function]_         `FAILED-REF-P  (OBJECT)`\n\n\u003e Returns T if the specified object is of type failed-ref.\n\n\n_[type]_             `LEAF-NODE  NIL`\n\n\u003e A LEAF-NODE represents a terminal value in a CTRIE arc.\n  LEAF-NODEs always contain a unit-payload of CTRIE data\n  storage; For example, an SNODE contains a key/value pair.\n\n\n_[type]_             `BRANCH-NODE  NIL`\n\n\u003e a BRANCH-NODE represents a single arc typically contained\n  within A CNODE.\n\n\n_[type]_             `MAIN-NODE  NIL`\n\n\u003e A MAIN-NODE is a node that typically represents a specific\n  depth or level within the ctrie and is referenced\n  by its own unique inode.\n\n\n_[structure]_        `INODE ()`\n\n\u003e An INODE, or 'Indirection Node' is the mutable structure\n  representing the link between other 'main-node' structures found in\n  a ctrie.  An inode is the only type of node that may change the\n  value of its content during its lifetime.  In this implementation,\n  all such values as may change are encapsulated within a `REF`\n  substructure.  Each inode also contains a generational descriptor\n  object, comparible by identity only, which is used to identify the\n  state of synchronization between the inode and the current\n  'generation' indicated by the root inode at the base of the\n  CTRIE. As an inode may not change its 'gen identity' during its\n  lifetime, this disparity with the generation of the root node will\n  immediately result in the replacement of the inode with a new one\n  properly synchronized with the root's `GEN` object. In this\n  implementation, `GEN` objects are implemented by GENSYMS -- unique,\n  uninterned symbols which inherently provide very similar symantics\n  to those required of the generational descriptor.\n  - `GEN` defines a slot containing a generational descriptor object\n  - `REF` defines a slot containing a `REF` struct that encapsulates\n    the mutable content within an INODE\n\n\n_[function]_         `INODE-P  (OBJECT)`\n\n\u003e Returns T if the specified object is of type inode.\n\n\n_[function]_         `INODE-GEN  (INODE)`\n\n\u003e Returns the gen of the specified inode\n\n\n\n_[function]_         `INODE-REF  (INODE)`\n\n\u003e Returns and (with setf) changes the ref of the specified inode\n\n\n\n_[function]_         `MAKE-INODE  (LINK-TO \u0026OPTIONAL GEN STAMP PREV)`\n\n\u003e Construct a new INODE that represents a reference to the value\n  provided by argument LINK-TO, optionally augmented with a specified\n  generational descriptor, timestamp, and/or previous state\n\n\n_[macro]_            `GCAS-COMPARE-AND-SET  (OBJ EXPECTED NEW EXPECTED-STAMP\n                                             NEW-STAMP PREV)`\n\n\u003e A thin, macro layer abstraction over the basic compare-and-swap\n  primitive which provides a consistent interface to the underlying\n  inode structure and manages additional metadata, providing\n  reasonable defaults when they are not specified.\n\n\n_[function]_         `INODE-READ  (INODE)`\n\n\u003e INODE-READ provides the top-level interface to the inode _GCAS ACCESS_\n  api, which is the mechanism which must be used to gain access to the\n  content of any NON-ROOT inode. For access to the root inode, refer\n  to the RDCSS inode api `ROOT-NODE-ACCESS`. Returns as four values,\n  the MAIN-NODE, the STAMP, the PREVIOUS STATE (if any), and the REF\n  structure encapsulated by the inode.\n\n\n_[function]_         `INODE-MUTATE  (INODE OLD-VALUE NEW-VALUE)`\n\n\u003e INODE-MUTATE provides the top-level interface to the inode _GCAS\n  MODIFICATION_ api, which is the mechanism which must be used to\n  effect any change in a NON-ROOT inode.  For modification of the\n  root-inode, refer to the `ROOT-NODE-REPLACE` _RDCSS ROOT NODE\n  PROTOCOL_ Returns a boolean value which indicates the success or\n  failure of the modification attempt.\n\n\n_[function]_         `INODE-COMMIT  (INODE REF)`\n\n\u003e INODE-COMMIT implements the _GCAS COMMIT_ protocol which is invoked\n  as necessary by the `INODE-READ` and `INODE-MUTATE` entry-points.  It is\n  not meant to be invoked directly, as this would most likely result\n  in corruption. Returns the `REF` structure representing the content of\n  whatever root inode wound up successfully committed -- either the\n  one requested, or one represented by a previous valid state.  In order\n  to coexist with the _RDCSS ROOT NODE PROTOCOL_ this GCAS COMMIT\n  implementation is augmented with RDCSS ABORTABLE READ semantics\n  by a forward reference to a RDCSS-aware `ROOT-NODE-ACCESS` in order\n  to safely compare INODE's generational descriptor with the one found\n  in the root inode of the subject CTRIE.\n\n\n_[function]_         `SNODE  (KEY VALUE)`\n\n\u003e Construct a new SNODE which represents the mapping from\n  domain-element KEY to range-element VALUE.\n\n\n_[structure]_        `SNODE ()`\n\n\u003e SNODE, i.e., 'Storage Node', is the LEAF-NODE structure ultimately\n  used for the storage of each key/value pair contained in the CTRIE.\n  An SNODE is considered to be immutable during its lifetime.\n   - `KEY` defines the slot containing an element of the map's domain.\n   - `VALUE` defines the slot containing the range-element mapped to `KEY`\n\n\n_[function]_         `SNODE-P  (OBJECT)`\n\n\u003e Returns T if the specified object is of type snode.\n\n\n_[function]_         `SNODE-KEY  (SNODE)`\n\n\u003e Returns the key of the specified snode\n\n\n\n_[function]_         `SNODE-VALUE  (SNODE)`\n\n\u003e Returns the value of the specified snode\n\n\n\n_[structure]_        `LNODE ()`\n\n\u003e LNODE, i.e., 'List Node', is a special structure used to enclose\n  SNODES in a singly-linked chain when the hash-codes of the\n  respective SNODE-KEYS collide, but those keys are determined to be\n  unique by the `CTRIE-TEST` function defined for that ctrie.  An\n  LNODE (and therefore a chain of LNODEs) is considered to be\n  immutable during its lifetime.  The order of the list is\n  implemented (arbitrarily) as most recently added first, analogous to\n  `CL:PUSH`\n   - `ELT` defines the slot containing an enclosed SNODE\n   - `NEXT` defines a slot referencing the next LNODE in the chain, or\n     `NIL` if no further LNODES remain.\n\n\n_[function]_         `LNODE-P  (OBJECT)`\n\n\u003e Returns T if the specified object is of type lnode.\n\n\n_[function]_         `LNODE-ELT  (LNODE)`\n\n\u003e Returns the elt of the specified lnode\n\n\n\n_[function]_         `LNODE-NEXT  (LNODE)`\n\n\u003e Returns the next of the specified lnode\n\n\n\n_[function]_         `ENLIST  (\u0026REST REST)`\n\n\u003e Construct a chain of LNODE structures enclosing the values supplied.\n  It is assumed (elsewhere) that each of these values is a valid SNODE\n  structure.\n\n\n_[function]_         `LNODE-REMOVED  (ORIG-LNODE KEY TEST)`\n\n\u003e Construct a chain of LNODE structures identical to the chain starting\n  with ORIG-LNODE, but with any LNODE containing an SNODE equal to KEY\n  removed.  Equality is tested as by the predicate function passed as\n  the argument TEST. The order of nodes in the resulting list will\n  remain unchanged.\n\n\n_[function]_         `LNODE-INSERTED  (ORIG-LNODE KEY VALUE TEST)`\n\n\u003e Construct a chain of LNODE structures identical to the chain starting\n  with ORIG-LNODE, but ensured to contain an LNODE enclosing an SNODE mapping\n  KEY to VALUE.  If the given KEY equal to a key already present somewhere\n  in the chain (as compared with equality predicate TEST) it will be\n  replaced.  Otherwise a new LNODE will be added. In either case, the LNODE\n  containing `(SNODE KEY VAlUE)` will be the first node in the resulting\n  list\n\n\n_[function]_         `LNODE-SEARCH  (LNODE KEY TEST)`\n\n\u003e Within the list of lnodes beginning with LNODE, return the range value\n  mapped by the first SNODE containing a key equal to KEY as determined\n  by equality predicate TEST, or `NIL` if no such key is found.  As a\n  second value, in order to support storage of `NIL` as a key, return `T` to\n  indicate that the KEY was indeed found during search, or `NIL` to indicate\n  that no such key was present in the list\n\n\n_[function]_         `LNODE-LENGTH  (LNODE)`\n\n\u003e Return the number of LNODES present in the chain beginning at LNODE\n\n\n_[structure]_        `TNODE ()`\n\n\u003e A TNODE, or 'Tomb Node', is a special node structure used to preserve\n  ordering during `CTRIE-DROP` (`%remove`) operations.\n  Any time a TNODE is encountered during the course of a `CTRIE-GET` (`%lookup`)\n  operation, the operative thread is required to invoke a `CLEAN` operation\n  on the TNODE it has encountered and throw to `:RESTART` its lookup activity\n  over again.  A TNODE is considered to be immutable and may not change its\n  value during its lifetime.\n   - `CELL` defines a slot which contains the entombed node structure.\n      Only LNODE and SNODE type nodes are ever entombed\n\n\n_[function]_         `TNODE-P  (OBJECT)`\n\n\u003e Returns T if the specified object is of type tnode.\n\n\n_[function]_         `TNODE-CELL  (TNODE)`\n\n\u003e Returns the cell of the specified tnode\n\n\n\n_[structure]_        `CNODE ()`\n\n\u003e A CNODE, or 'Ctrie Node' is a MAIN-NODE containing a vector of up\n  to `2^W` 'arcs' -- i.e., references to either an SNODE or INODE\n  structure, collectively referred to as `BRANCH-NODES.` Each CNODE\n  also contains a (fixnum) bitmap that describes the layout of which\n  logical indices within the total capacity of `2^W` arcs are actually\n  allocated within that node with BRANCH-NODES physically present.\n  For more specific details on these BITMAP and ARC-VECTOR\n  constituents, refer to the following related functions: `FLAG`\n  `FLAG-PRESENT-P` `FLAG-VECTOR` and `FLAG-ARC-POSITION. The CNODE\n  structure is considered to be immutable and arcs may not be added or\n  removed during its lifetime.  The storage allocated within a CNODE\n  is fixed and specified at the time of its creation based on the\n  value of BITMAP during initialization\n   - `BITMAP`\n   - `ARCS` \n\n\n_[function]_         `CNODE-P  (OBJECT)`\n\n\u003e Returns T if the specified object is of type cnode.\n\n\n_[function]_         `MAKE-CNODE  (\u0026OPTIONAL (BITMAP 0))`\n\n\u003e Construct a CNODE with internal storage allocated for the number of\n  arcs equal to the Hamming-Weight of the supplied BITMAP parameter.\n  If no BITMAP is provided, the CNODE created will be empty -- a state\n  which is only valid for the level 0 node referenced by the root of\n  the CTRIE.  This constructor is otherwise never called directly, but\n  is invoked during the course of higher-level operations such as\n  `CNODE-EXTENDED` `CNODE-UPDATED` `CNODE-TRUNCATED` and `MAP-CNODE`\n\n\n_[function]_         `CNODE-EXTENDED  (CNODE FLAG POSITION NEW-ARC)`\n\n\u003e Construct a new cnode structure that is exactly like CNODE, but\n  additionally contains the BRANCH-NODE specified by parameter NEW-ARC\n  and logical index FLAG at the physical index POSITION within its\n  vector of allocated arcs.  The BITMAP of this new CNODE will be\n  calculated as an adjustment of the prior CNODE's BITMAP to reflect\n  the presence of this additional arc.  In addition, the physical\n  index within the extended storage vector for the other arcs present\n  may also change with respect to where they were located in the prior\n  CNODE.  In other words, the physical index of a given arc within the\n  compressed CNODE storage vector should never be relied upon\n  directly, it should always be accessed by calculation based on its\n  LOGICAL index and the current CNODE BITMAP as described in more\n  detail by the documentation for the functions `FLAG` `FLAG-VECTOR` and\n  `FLAG-ARC-POSITION`\n\n\n_[function]_         `CNODE-UPDATED  (CNODE POSITION REPLACEMENT-ARC)`\n\n\u003e Construct a new cnode structure identical to CNODE, but having the\n  BRANCH-NODE physically located at POSITION within the storage\n  vector replaced by the one specified by REPLACEMENT-ARC.  Unlike\n  `CNODE-EXTENDED` and `CNODE-TRUNCATED` the allocated storage and\n  existing BITMAP of this CNODE will remain unchanged (as this is\n  simply a one-for-one replacement) and correspondingly, no reordering\n  of other nodes within the storage vector will occur\n\n\n_[function]_         `CNODE-TRUNCATED  (CNODE FLAG POS)`\n\n\u003e Construct a new cnode structure that is exactly like CNODE, but\n with the arc at logical index FLAG and physical storage vector\n location POS removed.  The new CNODE will have an updated bitmap\n value that is adusted to reflect the removal of this arc, and the\n position of other arcs within the storage vector of the new CNODE\n will be adjusted in a manner analogous to that of `CNODE-EXTENDED`\n More details on this process may be found by referring to the\n documentation for the functions `FLAG` `FLAG-VECTOR` and\n `FLAG-ARC-POSITION`\n\n\n_[function]_         `MAP-CNODE  (FN CNODE)`\n\n\u003e Construct a new cnode structure that is exactly like CNODE, but\n  with each arc (BRANCH-NODE) present in CNODE replaced by the result\n  of applying FN to that arc.  I.e., a simple functional mapping from\n  the old CNODE by FN.  As with `CNODE-UPDATED` the allocated storage and\n  BITMAP of the resulting CNODE will remain unchanged from the\n  original, and no physical reordering of nodes within the storage\n  vector will occur\n\n\n_[function]_         `CNODE-CONTRACTED  (CNODE LEVEL)`\n\n\u003e The _CONTRACTION_ of a CNODE is an ajustment performed when a CNODE\n  at depth other than level 0 contains only a single SNODE arc.  In\n  such a case, that SNODE is entombed in a new TNODE, which is\n  returned as the result of the CNODE contraction. In all other cases\n  the CNODE is simply returned as-is.  A CONTRACTION represents the\n  first of the two-step _ARC RETRACTION PROTOCOL_ that effects the reclaimation\n  of allocated storage no longer used and the optimization of of lookup\n  efficiency by compacting CTRIE depth and thereby the number of levels\n  which must be traversed.  For further information, refer to the function\n  `CNODE-COMPRESSED` which implements the second stage of this protocol,\n  completing the process.\n\n\n_[function]_         `CNODE-COMPRESSED  (CNODE LEVEL)`\n\n\u003e The _COMPRESSION_ of a CNODE is the second step of the _ARC\n  RETRACTION PROTOCOL_ completing a retraction that has been initiated\n  by `CNODE-CONTRACTED`.  The CNODE compression is computed by\n  generating a replacement cnode structure that is similar to CNODE,\n  but with any entombed inode arcs created during contraction simply\n  replaced by the SNODE that had been entombed. This is called the\n  _RESURRECTION_ of that SNODE. After all entombed inode arcs of a\n  cnode have been collapsed into simple SNODE leaves, if the resulting\n  CNODE has been compressed so far as to contain only a single SNODE\n  leaf, it is subjected to another CONTRACTION before it is returned\n  as the result of the compression. Otherwise it is simply returned\n  and represents a complete iteration of the _ARC RETRACTION PROTOCOL_\n\n\n_[function]_         `CLEAN  (INODE LEVEL)`\n\n\u003e CLEAN is the basic entry-point into the arc retraction protocol. Given an\n  arbitrary, non-root inode referencing a CNODE that can be compressed,\n  update that inode to reference the result of that compression.  Otherwise\n  INODE will remain unaffected.\n\n\n_[function]_         `CLEAN-PARENT  (PARENT-INODE TARGET-INODE KEY LEVEL)`\n\n\u003e During a `CTRIE-DROP` (`%remove`) operation, if the result of a KEY/VALUE\n  removal is an arc consisting of an `ENTOMBED` inode (one referencing a TNODE), then,\n  if that arc remains accessible from the parent of a CNODE containing it, generate\n  the compression of that CNODE and update its parent INODE with the result.\n\n\n_[structure]_        `RDCSS-DESCRIPTOR ()`\n\n\u003e An RDCSS-DESCRIPTOR object represents a 'plan' for a proposed RDCSS\n  (restricted double compare single swap) operation. The use of this\n  descriptor object provides the means to effect an atomic RDCSS in\n  software, requiring only hardware support for single-word CAS, which is\n  preferable because it is commonly available on curent consumer hardware.\n   - `OV`        designates a slot containing the OLD (current) root inode.\n                 If the swap is unsuccessful, the resulting ctrie will revert\n                 to this structure as the root inode. \n   - `OVMAIN`    designates a slot containing the CNODE that is referenced\n                 by the OLD (current) root inode.\n   - `NV`        designates a slot containing a fully assembled replacement\n                 root inode referencing a valid CNODE. This pair will become\n                 the root inode and level 0 MAIN-NODE of the ctrie if the\n                 swap is successful.\n   - `COMMITTED` designates a flag which, when not NIL, indicates that the\n                 RDCSS plan defined by this descriptor has completed\n                 successfully\n\n\n_[function]_         `RDCSS-DESCRIPTOR-P  (OBJECT)`\n\n\u003e Returns T if the specified object is of type rdcss-descriptor.\n\n\n_[function]_         `RDCSS-DESCRIPTOR-OV  (RDCSS-DESCRIPTOR)`\n\n\u003e Returns the ov of the specified rdcss-descriptor\n\n\n\n_[function]_         `RDCSS-DESCRIPTOR-OVMAIN  (RDCSS-DESCRIPTOR)`\n\n\u003e Returns the ovmain of the specified rdcss-descriptor\n\n\n\n_[function]_         `RDCSS-DESCRIPTOR-NV  (RDCSS-DESCRIPTOR)`\n\n\u003e Returns the nv of the specified rdcss-descriptor\n\n\n\n_[function]_         `RDCSS-DESCRIPTOR-COMMITTED  (RDCSS-DESCRIPTOR)`\n\n\u003e Returns and (with setf) changes the committed of the specified rdcss-descriptor\n\n\n\n_[function]_         `ROOT-NODE-ACCESS  (CTRIE \u0026OPTIONAL ABORT)`\n\n\u003e ROOT-NODE-ACCESS extends `FIND-CTRIE-ROOT`,\n  implementing the _RDCSS ROOT NODE PROTOCOL_ for access to root inode of\n  CTRIE.  In particular, it ensures that if, instead of an inode, the\n  root of CTRIE contains an RDCSS descriptor of a proposed root-node\n  update, that it will immediately invoke `ROOT-NODE-COMMIT` to act\n  on that descriptor and return an INODE struct that is the result of\n  the completed commit process. `ROOT-NODE-ACCESS` only provides access\n  to the root inode _STRUCTURE_ and in particular it does not provide\n  safe access to the _CONTENT_ of that inode. In order to access those\n  contents, the root inode returned by `ROOT-NODE-ACCESS` must be further\n  processed by `INODE-READ` in order to still properly comply with the\n  underlying GCAS protocol implementation requirements common to all\n  inodes\n\n\n_[function]_         `ROOT-NODE-REPLACE  (CTRIE OV OVMAIN NV)`\n\n\u003e ROOT-NODE-REPLACE implements the _RDCSS ROOT NODE PROTOCOL_ for\n  replacement of the ROOT INODE of a CTRIE structure with another one\n  that contains new or alternative values, achieving the end-result\n  effectively the same as if by mutation.  The replacement of the root\n  inode is accomplished in two, basic conceptual stages. First, an\n  `RDCSS-DESCRIPTOR` object which specifies in full the current state\n  and all desired changes in the proposed resulting state.  Thus,\n  whether any individual replacement attempt succeeds or fails, either\n  result is guarenteed to represent a valid state. An attempt is then\n  made to atomically swap this RDCSS-DESCRIPTOR with the current CTRIE\n  root inode.  Note that, although it contains all of the information\n  representing two, distinct, root inode states, the RDCSS-DESCRIPTOR\n  is not, itself, a valid root inode.  That is the reason why all\n  access to the root inode must be accomplished using this specialized\n  _RDCSS ROOT NODE PROTOCOL_ rather than just the _GCAS INODE\n  PROTOCOL_ alone, as is done with all other non-root inodes.  Once an\n  atomic compare-and-swap of an RDCSS-DESCRIPTOR object with the root\n  inode completes successfully, `ROOT-NODE-COMMIT` is invoked which\n  will attempt to complete the second step of this protocol.  The\n  result of that commit will be one or the other of the two valid\n  states defined in the RDCSS-DESCRIPTOR object.  If another thread\n  concurrently attempts access to a root node holding an\n  RDCSS-DESCRIPTOR object rather than an INODE, it will invoke\n  `ROOT-NODE-COMMIT` itself, possibly prempting our own attempt, but\n  guaranteeing nonblocking access to a valid root node by any concurrent\n  thread\n\n\n_[function]_         `ROOT-NODE-COMMIT  (CTRIE \u0026OPTIONAL ABORT)`\n\n\u003e rdcss api to complete a root-node transaction\n\n\n_[function]_         `CTRIE-SNAPSHOT  (CTRIE \u0026KEY READ-ONLY)`\n\n\u003e Atomically create a clone of CTRIE that may be operated upon\n  independently without affecting or being affected by operations or\n  content of the original CTRIE.  If READ-ONLY is NIL (the default),\n  the new CTRIE will be a READABLE/WRITABLE 'fork' of CTRIE (see\n  `CTRIE-FORK`) otherwise, the clone will be READABLE only, which has\n  considerable performance benefits in some circumstances, as the arcs\n  will not require `REFRESH` and should be the preferred mode when\n  updates (writability) of the clone are not required\n\n\n_[function]_         `CTRIE-CLEAR  (CTRIE)`\n\n\u003e Atomically clear all entries stored in CTRIE, returning it to a condition\n  which returns `T` when tested with predicate `CTRIE-EMPTY-P`\n\n\n_[function]_         `CTRIE-PUT  (CTRIE KEY VALUE)`\n\n\u003e Insert a new entry into CTRIE mapping KEY to VALUE.  If an entry\n  with key equal to KEY aleady exists in CTRIE, according to the\n  equality predicate defined by `CTRIE-TEST` then the priorbmapping\n  will be replaced by VALUE. Returns `VALUE` representing the\n  mapping in the resulting CTRIE\n\n\n_[function]_         `%INSERT  (INODE KEY VALUE LEVEL PARENT STARTGEN)`\n\n\u003e    -  The detailed specifics required to perform an insertion into a\n  CTRIE map are defined by and contained within the `%INSERT` function,\n  which is not part of the USER API and should never be invoked\n  directly.  The procedures required for interaction with `%INSERT` are\n  managed entirely by the upper layer entry-points and should be\n  entirely invisible to the developer using CL-CTRIE.  The alogorithm is\n  intricate and requires quite some effort to figure out based on the\n  papers and documentation. For that reason this attempt is made to\n  properly document the process -- not to encourage anyone to fiddle\n  with it...\n\n  \u003e 1.  A given call to %insert carries with it no guarantee that it will\n  actually succeed.  Further, there is no guarantee it will do anything\n  at all -- including ever returning to the caller having invoked it.\n  This is because there are a number of circumstances that may possibly\n  interfere with insertion in a lock-free concurrent data-structure and\n  in order to minimize the cost incurred by aborted attempts and\n  restarts, there is no effort wasted on careful condition handling or\n  recovery.  Instead, as soon as it is recognised that a particular\n  attempt will not succeed, Control is thrown via non-local exit\n  unceremoneously the entire call stack and restarting each time from\n  the very beginning. There are quite a few places within the process\n  where you will find these nonlocal exits. Originally I had in mind to\n  incorporate some additional insrumentation to track and gather\n  statistics the log the specifics of all this, and there are a number\n  of extension points provided.  For more details refer to the\n  `MULTI-CATCH` and `CATCH-CASE` control structure documentation.\n\n  \u003e 2.  %insert ALWAYS begins at an INODE.  This is not surprising, of\n  course, since the root of the tree (where all inserts begin) is an\n  INODE, and because INODES are the only nodes that provide\n  mutability. When we which to effect change to the CTRIE regardless of\n  where or what type, It may only be accomplished by mutating the parent\n  INODE immediately above it to reference content that must be freshly\n  regenerated each time changes are required.  Once it is established\n  that the %insert always begins at an inode, we can reason further\n  about the sequence of events that follow by considering some of the\n  node oriented invariants for CTRIEs specified variously in the\n  academic literature.  First, it has been clearly defined that an INODE\n  structure may only reference three kinds of structure that we\n  collectively refer to as MAIN-NODES.  These are the three potential\n  cases which we will consider next.\n\n  \u003e 3.  Consider first the TNODE. If indeed we follow an INODE and\n  discover it directly leads us to a TNODE, or 'Tomb Node'. This tells\n  us, first, that we have arrived at a dead-end, second that we must\n  assist with the 'compression' of this arc by invoking the `CLEAN`\n  operation on the tombed INODE's parent.  Finally, there is nothing\n  further we can do so we THROW to :RESTART.\n\n  \u003e 4.  If traverse the INODE and arrive at an LNODE, we are also at the\n  end of the ARC, but if it is due to hash collision then the algorithm\n  then indeed it may be correct.  In this case we attempt to 'insert'\n  ourself in te LNODE chain and then invoke INODE mutate to atomic\n  commit and then THROW to :RESTART\n\n  \u003e 5.  As a simple instance of the general case, we may arrive at a CNODE\n  with vacant arc that represents the index specified by the bits of our\n  KEY's hash code that are active for this level within the ctrie.  When\n  this is the case, we construct a replacement CNODE augmented with our\n  key/value pair as an SNODE LEAF at the physical position within the\n  CNODES storage vector appropriately translated from the logical arc\n  index as described by the documentation of the functions\n  `FLAG-ARC-POSITION` and `FLAG-VECTOR` If we successfully mutate the\n  parent inode by completing an atomic replacement of the old cnode with\n  the one we constructed, then our insertion has succeeded and we return\n  the range value now successfully mapped by KEY in order to indicate\n  our success.  Otherwise we THROW to :RESTART.\n\n  \u003e 6.  If we find the logical index of our 'arc' in this CNODE is not\n  empty and available as we did above, there are exactly two other\n  possibly find there; we know this because it is required to be a\n  BRANCH-NODE -- either an snode leaf storage or an inode referencing a\n  MAIN-NODE that represents the next layer of the CTRIE.  We describe\n  various posible cases and the define a procedure specified for each\n  below.\n\n  \u003e 7.  If we find that the node PRESENT at this index is an INODE, then\n  this is the simplest of the possible cases.  Conceptually, what we\n  intend to do is continue to follow our arc, descending to the next\n  level of the CTRIE structure that is referenced by that inode.  In\n  practice, however, we are required to consider the possibility that\n  the generational descriptor object the inode contains may not be\n  consistent with STARTGEN, which is the one current in the root INODE\n  of this CTRIE.  This may be the case, for example, as the result of\n  some past cloning/snapshot operation if we are the first since then to\n  traverse this inode. (Remember that the refresh of generational\n  descriptor occurs lazily on an as-needed basis in order to avoid\n  overhead incurred by eager traversals which often turn out to have\n  been unnecessary).  In consideration of this we proceeed as follows: -\n  If the inode generational descriptor is consistent with STARTGEN, we\n  simply continue along our arc by recursively invoking `%insert` on\n  that INODE.  If that function call returns successfully with a VALUE,\n  then the insertion was successful, and we also then return, passing\n  along that value.  Thus the result is communicated back through the\n  caller chain, eventually arriving back as the result of the original\n  CTRIE-PUT entry-point.  - Otherwise if the generational descriptor is\n  not consistent with STARTGEN we attempt an atomic `INODE-MUTATE` on\n  the PARENT INODE of this CNODE that effects the replacement of that\n  inode within it by one FRESHLY CREATED by `REFRESH` and ensured to be\n  consistent with STARTGEN.  If this succeeds, we invoke %insert\n  recusively and proceed in the same manner, since, effectively, we are\n  now in a state equivalent to the one described above.  - If the\n  INODE-MUTATE of the prior step did NOT succeed, then we are out of\n  options and throw to :RESTART the insertion process from the beginning\n  all over again.\n\n  \u003e 8.  If we find that the node PRESENT at this index is an SNODE,\n  then our situation becomes a little bit more complex and\n  there are a few more contingencies we must be prepared to\n  address.\n\n  \u003e 9.  Once again, looking at the simplest first, when an insert\n  operation encounters a leaf-node somewhere along the descent of it's\n  'own' arc, one potential case is that it found the node it was\n  looking for -- one that contains a key that satisfies the test\n  predicate defined for the dynamic extent of the current operation,\n  `CTEQUAL,` when compared to the `KEY` currently being `%INSERTED.`\n  If the equality test is satisfied then the VALUE that node maps\n  should be updated with the one of the present insertion.  The steps\n  to effect the update are very similar to those of step 5, however We\n  construct a replacement CNODE augmented with our key/value pair as a\n  replacement SNODE in the SAME physical position as the one we have\n  found -- refer to the documentation for the function `CNODE-UPDATED`\n  for additional specifics on the internal details that describe this\n  operation.  If we successfully mutate the parent inode by completing\n  an atomic replacement of the old cnode with the one we constructed,\n  then our update has succeeded and we return the range value now\n  successfully mapped by KEY in order to indicate our success.\n  Otherwise we THROW to :RESTART.\n\n  \u003e 10.  In some circumstances, we encounter a node on our arc whose\n  hash code bits have matched that of the current key of this\n  insertion for all of the lower order bits that have been consumed so\n  far, up to the current depth, but that (as opposed to step 9) does\n  not satisfy `CTEQUAL.` and so is NOT a candidiate for update\n  replacement.  Except in very vare circumstances, there will be some\n  depth at which the active bits of its hash code will indeed be\n  distinct from our own, and at that point a CNODE can be constructed\n  that will proprerly contain both it and an snode mapping the\n  key/value of the current insertion.  This means we must ENTEND the\n  ctrie as many layers as needed to get to that depth, inserting\n  CNODES and INODES at each step along the way.  Now, we will first\n  describe the 'edge' case where we have encounted the 'rare\n  circumstance.' If we perform this process and arrive at a depth\n  where all 32 hash code bits have been consumed and, indeed, these\n  two unequal keys are the result of a 'hash code collision' In order\n  that we preserve correct operation, we respond in this case by\n  chaining these key/value SNODES into a linked list of LNODES.\n  Therefore, they can share the same arc index and when we encounter\n  such a thing during future traversals, we can accomodate the\n  collision using simple linear search and a few basic LNODE utility\n  functions such as `LNODE-INSERTED` `LNODE-REMOVED` `LNODE-SEARCH`\n  `LNODE-LENGTH` and the list constructor `ENLIST.` Once we have\n  `ENLIST`ed the colliding SNODES, we create a new INODE pointing to\n  that list, and then attempt atomic replacement of the CNODE above\n  with one we extend to contain that INODE.  If we do successfully\n  mutate the prior CNODES parent INODE resulting in its replacement\n  with the CNODE we constructed, then our insert has succeeded and we\n  return the range value now successfully mapped by KEY in order to\n  indicate our success.  Otherwise we THROW to :RESTART.\n\n  \u003e 11.  Finally, let us return to those intermediate steps, mentioned\n  above, to specify the means by which we perform the level-by-level\n  extension of a given arc to accommodate both the above case of hash\n  collision as well as the more common one when the reason for\n  extension is simply to accomodate normal growth capacity and\n  allocation.  In both cases, though, the extensions are performed for\n  the same initiating cause -- to accomodate the collision of leaf\n  node keys resident at lower levels of the structure.  Depending on\n  the similarity of two colliding hash keys, the extension process may\n  not be resolved with a single iteration.  In the case of full\n  collisiion, described above, the extension process will recur, up to\n  a maximum depth of `(32/W)` levels, at which point an L-NODE chain\n  will be created.  At each iteration, a new INODE is created,\n  pointing to a new CNODE containing one of our conflictung pairs.\n  Then, `%INSERT` is attempted on that INODE and this process recurs.\n  Once this cycle of insert/extend completes, each INODE/CNODE pair is\n  returned to the parent -- the entire newly created structure\n  eventually returning to the point of original conflicts whre the\n  extension cycle began.  If we successfully mutate the parent inode\n  by completing an atomic replacement of the old cnode with the one\n  that begins this newly built structue, then our update has succeeded\n  and we return the range value now successfully mapped by KEY in\n  order to indicate our success.  Otherwise we THROW to :RESTART\n\n\n_[function]_         `CTRIE-GET  (CTRIE KEY)`\n\n\u003e Find the entry in CTRIE whose key is KEY and returns the\n  associated value and T as multiple values, or returns NIL and NIL\n  if there is no such entry. Entries can be added using SETF.\n\n\n_[function]_         `%LOOKUP  (INODE KEY LEVEL PARENT STARTGEN)`\n\n\u003e The general concept of the procedure for finding a given key within\n  a simplified SEQUENTIAL model of a CTRIE can be summarized as\n  follows: If the internal node is at level `L` then the W bits of the\n  hashcode starting from position `W * L` are used as a logical index\n  into the vector of `2^W` arcs that can possibly be represented\n  within that node (see `FLAG` and `FLAG-VECTOR`). This logical index\n  is then transformed into a physical index that denotes a specific\n  position locating this arc relative to all other arcs currently\n  present in the node (see `FLAG-ARC-POSITION`.  In this way, storage\n  within the node need not be allocated for representation of empty\n  arc positions. At all times the invariant is maintained that the\n  number of arcs allocated within a given CNODE is equal to the\n  Hamming-Weight of its BITMAP -- i.e., the number of nonzero bits\n  present (see `CL:LOGCOUNT`). The arc at this calculated relative\n  position is then followed, and the process repeated until arrival at\n  a leaf-node or empty arc position.  Locating a given key becomes\n  substantially more complicated in the actual lock-free concurrent\n  ctrie algorithm\n\n\n_[function]_         `CTRIE-DROP  (CTRIE KEY)`\n\n\u003e Remove KEY and it's associated value from CTRIE. Returns as multiple\n  values the value associated with KEY and T if there was such an entry,\n  otherewise NIL and NIL\n\n\n_[function]_         `%REMOVE  (INODE KEY LEVEL PARENT STARTGEN)`\n\n_[function]_         `CTRIE-MAP  (CTRIE FN \u0026KEY ATOMIC \u0026AUX ACCUM)`\n\n\u003e Applies a function two arguments, FN, to each (key . value) pair present in\n  CTRIE.  During the extent of CTRIE-MAP, a special variable ACCUM (initially NIL)\n  is available for accumulation of a result value which will be returned after\n  the completion of the CTRIE-MAP call.  If ATOMIC is non-NIL, the operation will\n  be performed on a read-only atomic snapshot of CTRIE, which guarantees a\n  consistent, point-in-time representation of the entries present in CTRIE\n\n\n_[macro]_            `CTRIE-DO  ((KEY VALUE CTRIE \u0026KEY ATOMIC) \u0026BODY BODY)`\n\n\u003e Iterate over the contents of CTRIE in the manner of dolist. For each\n  (key . value) pair present in CTRIE, BODY (implicit PROGN) will be\n  evaluated with the symbols specified for KEY and VALUE will be bound\n  to the respective entry constituents.  A special variable\n  ACCUM (initially NIL) is available for accumulation of a result\n  value which will be returned after the completion of the CTRIE-DO\n  call.  If ATOMIC is non-NIL, the operation will be performed on a\n  read-only atomic snapshot of CTRIE, which guarantees a consistent,\n  point-in-time representation of the entries present in CTRIE.\n  ```\n  ;;;  EXAMPLE: (ctrie-do (k v ctrie)\n  ;;;             (format t \"~\u0026~8S =\u003e ~10S~%\" k v))\n  ```\n\n\n_[function]_         `CTRIE-MAP-KEYS  (CTRIE FN \u0026KEY ATOMIC)`\n\n\u003e Applies a function one argument, FN, to each key present in CTRIE.\n  During the extent of CTRIE-MAP-KEYS, a special variable\n  ACCUM (initially NIL) is available for accumulation of a result\n  value which will be returned after the completion of the\n  CTRIE-MAP-KEYS call.  If ATOMIC is non-NIL, the operation will be\n  performed on a read-only atomic snapshot of CTRIE, which guarantees\n  a consistent, point-in-time representation of the keys present in\n  CTRIE\n\n\n_[function]_         `CTRIE-MAP-VALUES  (CTRIE FN \u0026KEY ATOMIC)`\n\n\u003e Applies a function one argument, FN, to each value present in CTRIE.\n  During the extent of CTRIE-MAP-VALUES, a special variable\n  ACCUM (initially NIL) is available for accumulation of a result\n  value which will be returned after the completion of the\n  CTRIE-MAP-VALUES call.  If ATOMIC is non-NIL, the operation will be\n  performed on a read-only atomic snapshot of CTRIE, which guarantees\n  a consistent, point-in-time representation of the values present in\n  CTRIE\n\n\n_[function]_         `CTRIE-KEYS  (CTRIE \u0026KEY ATOMIC)`\n\n\u003e Construct and return a list containing all keys present in CTRIE.\n  If ATOMIC is non-NIL, the operation will be performed on a read-only\n  atomic snapshot of CTRIE, which guarantees a consistent,\n  point-in-time representation of the keys present in CTRIE\n\n\n_[function]_         `CTRIE-VALUES  (CTRIE \u0026KEY ATOMIC)`\n\n\u003e Construct and return a list containing all values present in CTRIE.\n  If ATOMIC is non-NIL, the operation will be performed on a read-only\n  atomic snapshot of CTRIE, which guarantees a consistent,\n  point-in-time representation of the values present in CTRIE\n\n\n_[function]_         `CTRIE-SIZE  (CTRIE \u0026KEY ATOMIC \u0026AUX (ACCUM 0))`\n\n\u003e Return the number of entries present in CTRIE.  If ATOMIC is non-NIL,\n  the operation will be performed on a read-only atomic snapshot of CTRIE,\n  which guarantees a consistent, point-in-time representation of CTRIE\n\n\n_[function]_         `CTRIE-EMPTY-P  (CTRIE)`\n\n\u003e Return T if CTRIE contains no entries, otherwise NIL. This function is\n  O(1) and is much more efficient than testing for `CTRIE-SIZE` of 0\n\n\n_[function]_         `CTRIE-TO-ALIST  (CTRIE \u0026KEY ATOMIC)`\n\n\u003e Return an alist containing all (key . value) pairs found in CTRIE.\n  If ATOMIC is non-NIL, the operation will be performed on a read-only\n  atomic snapshot of CTRIE, which guarantees a consistent,\n  point-in-time representation of the entries in CTRIE\n\n\n_[function]_         `CTRIE-TO-HASHTABLE  (CTRIE \u0026KEY ATOMIC HASH-TABLE \u0026AUX\n                                           (ACCUM\n                                            (OR HASH-TABLE\n                                                (MAKE-HASH-TABLE :TEST\n                                                                 (CTRIE-TEST\n                                                                  CTRIE)\n                                                                 :HASH-FUNCTION\n                                                                 (CTRIE-HASH\n                                                                  CTRIE)\n                                                                 :SYNCHRONIZED\n                                                                 ATOMIC))))`\n\n\u003e Return a hash-table containing all (key . value) pairs found in CTRIE.\n  If ATOMIC is non-NIL, the operation will be performed on a read-only\n  atomic snapshot of CTRIE, which guarantees a consistent,\n  point-in-time representation of the entries in CTRIE. If HASH-TABLE\n  is specified, it will be used as the destination hash-table.\n  Otherwise, a new hash-table will be created with hash-function and\n  test identical to that of CTRIE.  It will be created as synchronized\n  if ATOMIC is not NIL\n\n\n_[function]_         `CTRIE-PPRINT  (CTRIE \u0026OPTIONAL (STREAM T))`\n\n\u003e Pretty-print a representation of CTRIE as an alist containing\n  all (key . value) pairs found in it.  Atomicity is not guaranteed\n\n\n_[function]_         `CTRIE-FROM-ALIST  (ALIST \u0026KEY CTRIE)`\n\n\u003e Return a CTRIE containing all (key . value) pairs found in ALIST.\n  If CTRIE is specified, it will be used as the destination ctrie.\n  Otherwise, a new ctrie will be created. Atomicity is not guaranteed\n\n\n_[function]_         `CTRIE-FROM-HASHTABLE  (HASH-TABLE \u0026KEY CTRIE)`\n\n\u003e Return a CTRIE containing all (key . value) pairs found in HASH-TABLE.\n  If CTRIE is specified, it will be used as the destination ctrie.\n  Otherwise, a new ctrie will be created with test identical to that\n  of HASH-TABLE. The hash-function will NOT be preserved, as that\n  information does not appear to be recoverable from a hash-table once\n  created\n\n\n_[function]_         `CTRIE-MAX-DEPTH  (THING)`\n\n\u003e Compute the maximum length of any arc. Useful as a diagnostic\n\n\n_[function]_         `CTRIE-MIN-DEPTH  (THING)`\n\n\u003e Compute the minimum length of any arc. Useful as a diagnostic\n\n\n_[function]_         `CTRIE-SNAPSHOT  (CTRIE \u0026KEY READ-ONLY)`\n\n\u003e Atomically create a clone of CTRIE that may be operated upon\n  independently without affecting or being affected by operations or\n  content of the original CTRIE.  If READ-ONLY is NIL (the default),\n  the new CTRIE will be a READABLE/WRITABLE 'fork' of CTRIE (see\n  `CTRIE-FORK`) otherwise, the clone will be READABLE only, which has\n  considerable performance benefits in some circumstances, as the arcs\n  will not require `REFRESH` and should be the preferred mode when\n  updates (writability) of the clone are not required\n\n\n_[function]_         `CTRIE-FORK  (CTRIE)`\n\n\u003e Atomically create a READABLE and WRITABLE clone of CTRIE that may\n  be operated upon independently without affecting or being affected\n  by the original CTRIE.\n\n\n_[macro]_            `CTRIE-LAMBDA  (\u0026ONCE CTRIE \u0026REST REST)`\n\n\u003e Pandoric Object and Inter-Lexical Communication Protocol\n  this macro builds the most unencumbered and widely applicable\n  'purist edition' Of our PLAMBDA based form.  Even as such,\n  a lot of care has been given to many subtle ways it has been\n  refined to offer the most convenient and natural tool possible.\n  ```;;;\n     ;;; (plambda (#\u003cCLOSURE (LAMBDA (\u0026REST ARGS)) {100929EB1B}\u003e )\n     ;;;\n     ;;; DISPATCHING to FUNCTIONAL MAPPING:\n     ;;;   (IF (REST ARGS)\n     ;;;          (APPLY ARG (REST ARGS))\n     ;;;          (FUNCALL ARG #'IDENTITY)) =\u003e\n     ;;; ------------------------------------------------------------\n     ;;; INITIALIZING PLAMBDA\n     ;;; ------------------------------------------------------------\n     ;;;   IT =\u003e #S(CTRIE\n     ;;;               :READONLY-P NIL\n     ;;;               :TEST EQUAL\n     ;;;               :HASH SXHASH\n     ;;;               :STAMP #\u003cCLOSURE (LAMBDA # :IN CONSTANTLY) {10092B516B}\u003e\n     ;;;               :ROOT #S(INODE\n     ;;;                        :GEN #:|ctrie2196|\n     ;;;                        :REF #S(REF\n     ;;;                                :STAMP @2012-08-19T13:34:58.314457-04:00\n     ;;;                                :VALUE #S(CNODE :BITMAP 0 :ARCS #())\n     ;;;                                :PREV NIL)))\n     ;;;   PLIST =\u003e (:CONTAINER #\u003cCLOSURE (LAMBDA #) {100929EACB}\u003e \n     ;;;             :TIMESTAMP @2012-08-19T13:34:58.314464-04:00)\n     ;;;   STACK =\u003e (#\u003cCLOSURE (LAMBDA #) {100929EACB}\u003e)\n     ;;; \n     ;;; ------------------------------------------------------------\n     ;;;  #\u003cCLOSURE (LAMBDA (\u0026REST #:ARGS55)) {100929EACB}\u003e\n     ;;;```\n\n\n_[generic-function]_ `CTRIE-LAMBDA-CTRIE  (CTRIE-LAMBDA-OBJECT)`\n\n\u003e Returns and (with setf) changes the ctrie of the specified ctrie-lambda-object\n\n\n\n_[function]_         `CTRIE-LAMBDA-SPAWN  (SELF \u0026KEY READ-ONLY)`\n\n\u003e Causes the atomic clone of enclosed ctrie structure and builds a new\n  lexical closure to operate on it.  Does not bother to reproduce fancy\n  (expensive) object, class, bindings, but provides almost identical\n  functionality.  May be used to more efficintly distribute workload\n  in parallel\n\n\n_[macro]_            `DEFINE-CTRIE  (NAME CTRIE \u0026REST ARGS \u0026KEY (OBJECT T) SPEC)`\n\n\u003e Define a 'functional' __CTRIE-LAMBDA__ that combines all the the\n  capabilities of the raw data structure with behavior and semantics\n  one would expect of any other ordinary common-lisp function.  The\n  resulting symbol defined as 'name will be bound in three distinct\n  namespaces: the `SYMBOL-VALUE` will be bound to the LAMBDA CLOSURE\n  object, `SYMBOL-FUNCTION` (fdefinition) will be FBOUND to the\n  compiled function, and the corresponding '(SETF NAME) form will be\n  SETF-BOUND.  the syntax for invoking NAME is as in a LISP1; i.e., no\n  'funcall' is required (but still works if you prefer).\n  Calling `(NAME key)` returns the value mapped to key, or `NIL` just\n  as if by `(CTRIE-GET ctrie-name key).` Analogously when used as a\n  setf-able place such as by `(setf (NAME key) value)` it has the\n  equivalent behavior to the operation `(CTRIE-PUT ctrie-name key\n  value).` Use of this type of binding technique has some really\n  convenient effects that I've quickly started to become quite fond\n  of.  One such idiom, for example, `(mapcar MY-CTRIE '(key1 key2 key3\n  key4 ...))` returns a list containing all the mapped values\n  corresponding to the respective keys.  One additional feature that\n  I've found extremely useful is included _under the hood:_ Invoking\n  MY-CTRIE on an object of type FUNCTION will not search the ctrie for\n  an entry having that function ast its key, but will instead APPLY\n  that function to the actual CTRIE structure wrapped within the\n  closure.  Thus, `(MY-CTRIE #'identity)` will return the underlying\n  ctrie as just an ordinary instance of a CTRIE STRUCTURE.  \n  There are many other functions this is handy with, like\n  `(MY-CTRIE #'ctrie-size)` `(MY-CTRIE #'ctrie-to-hashtable)`\n  etc.  Some additional examples are provided below.\n  ```\n  ;;;  (define-ctrie my-ctrie)\n  ;;;    =\u003e  MY-CTRIE\n  ;;;\n  ;;;  (describe 'my-ctrie)\n  ;;;\n  ;;;     CL-CTRIE::MY-CTRIE\n  ;;;       [symbol]\n  ;;;    \n  ;;;     MY-CTRIE names a special variable:\n  ;;;       Value: #\u003cCLOSURE (LAMBDA # :IN MAKE-CTRIE-LAMBDA) {100F73261B}\u003e\n  ;;;    \n  ;;;     MY-CTRIE names a compiled function:\n  ;;;       Lambda-list: (\u0026REST ARGS1)\n  ;;;       Derived type: FUNCTION\n  ;;;    \n  ;;;     (SETF MY-CTRIE) names a compiled function:\n  ;;;       Lambda-list: (VALUE KEY)\n  ;;;       Derived type: (FUNCTION (T T) *)\n  ;;;\n  ;;;\n  ;;;   (my-ctrie :HONG-KONG :FOOY)\n  ;;;     =\u003e  :FOOY\n  ;;;\n  ;;;   (my-ctrie :HONG-KONG)\n  ;;;     =\u003e  :FOOY ; T\n  ;;;\n  ;;;   (map 'list #'eval (mapcar #`(my-ctrie ,a1 ,a1) (iota 12)))\n  ;;;     =\u003e  (0 1 2 3 4 5 6 7 8 9 10 11)\n  ;;;\n  ;;;   (mapcar my-ctrie (iota 12))\n  ;;;     =\u003e  (0 1 2 3 4 5 6 7 8 9 10 11)\n  ```\n\n\n_[macro]_            `CTRIE-ERROR  (CONDITION \u0026REST ARGS)`\n\n\u003e Signal a CTRIE related condition.\n\n\n_[condition]_        `CTRIE-ERROR (ERROR)`\n\n\u003e Abstract superclass of CTRIE related conditions.\n\n\n_[condition]_        `CTRIE-STRUCTURAL-ERROR (CTRIE-ERROR)`\n\n\u003e Condition designating that the CTRIE data structure\n   has been determined to be invalid.\n\n\n_[condition]_        `CTRIE-OPERATIONAL-ERROR (CTRIE-ERROR)`\n\n\u003e Condition for when an operational failure or\n  inconsistency has occurred.\n\n\n_[function]_         `CTRIE-MODIFICATION-FAILED  (REASON \u0026KEY OP PLACE)`\n\n\u003e Signal a modification failure with the appropriate attendant metadata.\n\n\n_[condition]_        `CTRIE-MODIFICATION-FAILED (CTRIE-OPERATIONAL-ERROR)`\n\n\u003e This condition indicates an unhandled failure of an attempt to\n         perform stateful modification to CTRIE.  The most common case in\n         which this might occur is when such an attempt is mode on a CTRIE\n         designated as READONLY-P.  In any case, this condition represents an\n         exception from which processing cannot continue and requires\n         interactive user intervention in order to recover.\n\n\n_[condition]_        `CTRIE-OPERATION-RETRIES-EXCEEDED (CTRIE-OPERATIONAL-ERROR)`\n\n\u003e Condition indicating an operation has failed the\n   maximum number of times specified by the special-variable\n   *retries*\n\n\n_[condition]_        `CTRIE-NOT-IMPLEMENTED (CTRIE-ERROR)`\n\n\u003e Condition designating functionality for which the\n   implementation has not been written, but has not been deliberately\n   excluded.\n\n\n_[condition]_        `CTRIE-NOT-SUPPORTED (CTRIE-ERROR)`\n\n\u003e Condition designating functionality that is\n  deliberately not supported.\n\n\n_[condition]_        `CTRIE-INVALID-DYNAMIC-CONTEXT (CTRIE-OPERATIONAL-ERROR)`\n\n\u003e Condition indicating an operation was attempted\n   outside the dynamic extent of a valid enclosing WITH-CTRIE form\n\n\n_[condition]_        `CTRIE-GENERATIONAL-MISMATCH (CTRIE-STRUCTURAL-ERROR)`\n\n\u003e Condition indicating an operation encountered an\n   outdated or inconsistent node during its attempted traversal\n\n\n_[function]_         `README  (\u0026OPTIONAL (STREAM *STANDARD-OUTPUT*))`\n\n\u003e Update documentation sections of the README file. When an output stream\n  is specified, the results are also echoed to that stream. To inhibit\n  output, invoke as `(readme (make-broadcast-stream))` or use `README-QUIETLY`\n\n\n_[function]_         `README-QUIETLY  ()`\n\n\u003e Update documentation sections of the README file, inhibiting any other\n  printed output.\n\n\n_[function]_         `APIDOC  (\u0026OPTIONAL (SCOPE :EXTERNAL))`\n\n\u003e Collect a list of strings representing the documentation for\n  CL-CTRIE rendered in a compact format suitable for inclusion in a\n  lightweight text-markup format document.  If SCOPE is specified it\n  must be either :EXTERNAL. corresponding to those symbols exported as\n  the public API, or :HOME, which designates all symbols defined\n  locally in package.\n\n\n_[function]_         `PRINC-APIDOC  (\u0026OPTIONAL (SCOPE :EXTERNAL))`\n\n\u003e Print to `*STANDARD-OUTPUT*` the documentation for CL-CTRIE rendered\n  in a compact format.  This is intended primarily as a convenience to\n  the interactive user seeking quick reference at the REPL.  If SCOPE\n  is specified it must be either :EXTERNAL. corresponding to those\n  symbols exported as the public API, or :HOME, which designates all\n  symbols defined locally in package.\n\n\n_[function]_         `COLLECT-DOCS  (\u0026OPTIONAL (SCOPE :EXTERNAL)\n                                     (SORT #'STRING\u003c))`\n\n\u003e Regenerate on-disk html documentation and collect the cached\n  in-memory descriptors for further processing. If SCOPE is specified\n  it must be either :EXTERNAL. corresponding to those symbols exported\n  as the public API, or :HOME, which designates all symbols defined\n  locally in package.  Output order may be customized by an optionally\n  specified SORT function.\n\n\n_[macro]_            `DEFINE-DIAGRAM  (TYPE (\u0026OPTIONAL CONTEXT) \u0026BODY BODY)`\n\n\u003e Define a diagrammatic representation of TYPE, optionally specialized\n  for a specific CONTEXT. See {defgeneric cl-ctrie::make-diagram}.\n\n\n* * * * * * *\n","funding_links":[],"categories":["Expert Systems"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanlentz%2Fcl-ctrie","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanlentz%2Fcl-ctrie","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanlentz%2Fcl-ctrie/lists"}