This is C++ code to illustrate how an Arrow Space works. The actual prototype has a C interface.
#include <cstdint>
#include <string>
#include <functional>
class XLEnum;
class XLArrow {
public:
using ID = uint32_t;
using XLCallBack = std::function<ID(Arrow arrow, Arrow context)>;
using enum XLType {
XL_UNDEF = -1,
XL_EVE = 0,
XL_PAIR = 1,
XL_ATOM = 2
};
static constexpr ID NIL = 0xFFFFFFFFU;
static constexpr ID EVE = 0;
// Construction of transient arrows
// ------------------
XLArrow(); // build a Eve copy
XLarrow(XLArrow tail, XLArrow head)
XLarrow(const XLArrow* tail, const XLArrow* head); // pair of arrows
explicit XLarrow(const char* str); // C-string Atom
explicit XLarrow(uint32_t size, const uint8_t* data); // Binary Atom
explicit XLArrow(const std::string& uri); // Assimilate an URI. Returns an arrow or NIL if bad URI
explicit XLArrow(const std::string_view uri_part); // Assimilate a piece of URI. Returns an arrow or NIL if bad URI
// ... assignement
XLArrow(const XLArrow&);
XLArrow& operator=(const XLArrow&) = default;
// Assimilation (getting singletons)
// ------------------
XLArrow assimilate(); // assimilate arrow by getting its corresponding singleton
XLArrow resolve(); // assimilate arrow by getting its singleton if found otherwhise return this
// Getters (they don't assimilate)
// ------------------
ArrowID getID() { return ID; }
XLType getType() const; // Get arrow type
XLArrow getHead() const; // Get arrow head
XLArrow getTail() const; // Get arrow tail
uint32_t getChecksum() const; // Get arrow hash/checksum
char* getDigest(uint32_t* size_p) const; // Get arrow digest. Returns pointer to allocated memory
char* getUri(uint32_t* size_p) const; // Get arrow definition in URI notation. Returns pointer to allocated memory
// Getters for Atoms (TODO Sub-class)
// ------------------
char* getStr() const; // Get atomic arrow as a C string. Null terminator added. Returns allocated memory or null if pair
uint8_t* getMem(uint32_t& size) const; // Get atomic arrow as binary data. size updated. No extra null terminator added. Returns allocated memory or null if pair
void* getPointer() const; // Get the C pointer of a "hook" arrow, otherwise NULL or null if not "hook"
// Testing (resolve but don't assimilate)
// ------------------
bool isEve() const; // Returns true if equals Eve
bool isKnown() { return resolve().singleton != NULL }; // Return true if known
XLArrow isRooted() const; // Returns this if rooted, Eve otherwise
XLArrow equal(const XLArrow& other) const; // Returns this if equals other, Eve otherwise
XLArrow isAtom() const; // Returns this if an atom, Eve otherwise
XLArrow isPair() const; // Returns this if a pair, Eve otherwise
// Rooting
// ------------------
XLArrow root(); // Assimilate and root arrow, return singleton
XLArrow unroot(); // Resolve and unroot arrow, return resolved arrow (this if no singleton)
// Assimilated Arrow factories (factories of Singletons)
// ------------------
static XLArrow eve(); // Returns Eve
static XLArrow pair(const XLArrow* tail, const XLArrow* head); // Assimilate a pair of arrows
static XLArrow atom(const char* str); // Assimilate a C string
static XLArrow atomn(uint32_t size, const uint8_t* data); // Assimilate raw data
static XLArrow uri(const char* uriStr); // Assimilate an URI. Returns an arrow or NIL if bad URI
static XLArrow urin(uint32_t size, const char* uriStr); // Assimilate a piece of URI. Returns an arrow or NIL if bad URI
// Compound arrow factories
// ------------------
static XLArrow anonymous(); // Assimilate a randomized value to get a unique "anonymous" arrow
static XLArrow hook(void* hook); // Assimilate a C pointer and return an arrow
// Arrow resolving without assimilation
// ----------------------------------
static XLArrow pairMaybe(const XLArrow* head, const XLArrow* tail); // Return the resolved singleton for this pair otherwise a transient XLArrow
static XLArrow atomMaybe(const char* str); // Return the resolved singleton for this string otherwise a transient XLArrow
static XLArrow atomnMaybe(uint32_t size, const uint8_t* data); // Return the resolved singleton for this binary string otherwise a transient XLArrow
static XLArrow uriMaybe(const char* uriStr); // Return the resolved singleton for this URI otherwise a transient XLArrow
static XLArrow urinMaybe(uint32_t size, const char* uriStr); // Return the resolved singleton for this URI part otherwise a transient XLArrow
static XLArrow digestMaybe(const char* digest); // Return the resolved singleton for this digest otherwise a transient XLArrow
// Browsing methods (resolve but don't assimilate)
// ------------------
XLEnum* childrenOf(); // Return an enumerator of children
void childrenOfCB(XLCallBack callback, XLArrow context); // Call back with every child
// System Life Cycle
// ------------------
static int init(); // System initialization
static void destroy(); // Release resources and locks
// Transactions
// ------------------
static void begin(); // Open a transaction
static void over(); // Release a transaction
static void commit(); // Wait for all transactions and commit.
static void yield(const XLArrow& state); // Wait for all transactions and perform a GC without commiting, removing all loose arrows but a "state" arrow
private:
xl_arrow_def_t def; // the transient definition
ID id = NIL; // the arrow id
XLArrow* singleton = NULL; // the corresponding assimilated Arrow, NULL is not solved, this if singleton
};
class XLEnum {
public:
XLEnum();
~XLEnum() = default;
bool next(); // Iterate enumerator. Return false if over or broken, true otherwise
XLArrow get() const; // Get current arrow from enumerator
};