/* * e4graph.h -- * * This file contains the definition of the public interface part of the * e4Graph library. It defines the following classes: * * e4_RefCount -- A base class used to manage lifecycle. * e4_Storage -- A representation of tree data storage. * e4_Node -- A representation of a node. * e4_Vertex -- A representation of a vertex. * e4_StorageVisitor -- * A visitor ranging over the currently open * storages. * e4_VertexVisitor-- A visitor ranging over various selections of * vertices in a storage. * e4_NodeVisitor -- A visitor ranging over the nodes in a storage. * * Some utility classes are also defined here: * * e4_HashTable -- A hash table for use with e4Graph. * e4_HashEntry -- A hash entry in a hash table. * e4_HashSearch -- A way to search through a hash table. * e4_DString -- A dynamic string facility that grows efficiently. * * Copyright (c) 2000-2003, JYL Software Inc. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE, EVEN IF * JYL SOFTWARE INC. IS MADE AWARE OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __E4_GRAPH_H__ #define __E4_GRAPH_H__ /* * Version string (updated each release): */ #define E4GRAPH_VERSION "1.0a11" /* * Enumeration defining the possible release status codes: */ typedef enum e4_ReleaseStatus { E4_ALPHARELEASE = 0, E4_BETARELEASE = 1, E4_FINALRELEASE = 2, E4_PATCHRELEASE = 3 } e4_ReleaseStatus; /* * Version numbers (updated each release): */ #define E4GRAPH_MAJOR 1 #define E4GRAPH_MINOR 0 #define E4GRAPH_RELEASESTATUS E4_ALPHARELEASE #define E4GRAPH_RELEASEITER 11 /* * These are the names of the built-in drivers: */ #define E4_METAKIT "Metakit 2.4" /* * Make export declarations work for WIN32. */ #ifndef e4_DLL # if defined(_WIN32) && !defined(E4_STATIC) # ifdef E4_DLL # define e4_DLL __declspec(dllexport) # else # define e4_DLL __declspec(dllimport) # endif # else # define e4_DLL # endif #endif #ifndef e4_DLLSPEC # ifdef _WIN32 # define e4_DLLSPEC(t) e4_DLL t # else # define e4_DLLSPEC(t) t e4_DLL # endif #endif /*********************************************************************** * * e4Graph public APIs proper: * *********************************************************************** */ /* * These config parameters are lifted from metakit-2.4.3/include/mk4.h. */ /* * Borland C++ and C++ Builder */ #if defined (__BORLANDC__) /* * Borland 5.0 supports the bool datatype */ #if __BORLANDC__ >= 0x500 #define e4_BOOL 1 #endif #define E4_NO_CAST #endif /* * Metrowerks CodeWarrior */ #if defined (__MWERKS__) #if __option(bool) #define e4_BOOL 1 #undef bool #undef true #undef false #endif #define E4_NO_CAST #endif /* * Microsoft Visual C++ */ #if defined (_MSC_VER) /* * MSVC 5.0 supports the bool datatype, MSVC 4.x has no namespaces */ #if _MSC_VER >= 1100 #define e4_BOOL 1 #endif #include #define E4_NO_CAST #endif /* * Symantec C++, Contributed by John Fletcher. */ #if defined(__SC__) #ifdef _BOOL_DEFINED #define e4_BOOL 1 #endif #endif /* * GNU C++ has a bool. */ #if defined (__GNUC__) #define e4_BOOL 1 #endif /* * If no bool definition is provided, define one. */ #if !e4_BOOL #define false 0 #define true 1 #define bool int #endif /* * Add casts for compilers that need them. */ #ifdef E4_NO_CAST #define E4_CONST_VOID_STAR #define E4_CONST_CHAR_STAR #else #define E4_CONST_VOID_STAR (const void *) #define E4_CONST_CHAR_STAR (const char *) #endif /* * Public #define values. */ #define E4_VERTEXNOTFOUND -1 /* A vertex with the given name * could not be found in this * node. */ #define E4_VERTEXNOTCREATED -1 /* Some kind of failure during * vertex creation. */ #define E4_NODENOTCREATED -1 /* Some kind of failure during * node creation. */ #define E4_NODENOTFOUND -2 /* A requested node could not * be found. */ #define E4_RANKNOTUSED -1 /* Constant to pass to operations * that take a rank, to denote that * the value is meaningless. */ #define E4_INVALIDUNIQUEID -1 /* Constant that denotes an invalid * unique ID. */ /* * These state bits control various behaviors of a storage at runtime. * They are not persistent. The various states are: * * E4_COMMITATCLOSE If on, a commit is done before closing * the storage. On by default. * E4_AUTOCOMMIT If on, a commit is done periodically when * changes exist in the storage. Not yet * implemented. Off by default. * E4_OPENGC If on, a garbage collection is performed * when the storage is opened. On by default. * E4_GCBEFORECOMMIT If on, a garbage collection is performed * before every commit (both auto-commit and * explicit commit). Off by default. * E4_AUTOGC If on, a garbage collection is performed * whenever an entity (node or vertex) becomes * unreachable, to reclaim all unreachable * space in the storage. If a large number of * changes are applied to a storage, it is useful * to delay garbage collection until all changes * have been applied. Turning off this mode will * achieve that effect. On by default. * E4_BIGPREALLOC If on, space is pre-allocated in the storage * in big increments. The default is to allocate * storage in relatively smaller increments. This * mode is intended for when a large number of * entities will be created in a sequence of * calls; this optimizes the amount of work * that e4Graph has to do to make space for new * entities as they are added to the storage. * Off by default. * E4_COMPACTATCLOSE If on, space is compacted when the storage * is closed. This makes the storage as small * as possible while preserving the logical * structure of the data graph. Not yet * implemented. Off by default. * E4_NOVERTEXCACHE If on, this storage does not allow caching * vertex IDs indexed by vertex names and rank. * E4_IMMEDIATEGC If on, GC occurs immediately when an entity * becomes unreachable. Off by default. */ #define E4_COMMITATCLOSE (1<<0) #define E4_AUTOCOMMIT (1<<1) #define E4_OPENGC (1<<2) #define E4_GCBEFORECOMMIT (1<<3) #define E4_AUTOGC (1<<4) #define E4_BIGPREALLOC (1<<5) #define E4_COMPACTATCLOSE (1<<6) #define E4_NOVERTEXCACHE (1<<7) #define E4_IMMEDIATEGC (1<<8) /* * These macros allow setting and unsetting of individual bits in the state * of a storage: */ #define SETSTATE(s, b) \ { \ int __oldstate__, __newstate__; \ \ __oldstate__ = (s).GetState(); \ __newstate__ = (__oldstate__ | (b)); \ (void) (s).SetState(__newstate__); \ } #define CLEARSTATE(s, b) \ { \ int __oldstate__, __newstate__; \ \ __oldstate__ = (s).GetState(); \ __newstate__ = (__oldstate__ & (~(b))); \ (void) (s).SetState(__newstate__); \ } #define HASSTATE(s, b) (((s).GetState() & (b)) == (b)) /* * These states are on by default. */ #define E4_DEFAULTSTATE (E4_COMMITATCLOSE | E4_OPENGC | E4_AUTOGC) /* * These defined constants advise a node's cache management policy: */ #define E4_CACHEINCREMENTAL 0 #define E4_AUTOCACHENAMES (1<<0) #define E4_AUTOCACHERANKS (1<<1) /* * Get needed definitions from the operating system: */ #include /* * Get needed definitions from the standard C++ library. */ #include #include /* * Forward declarations: */ class e4_DLL e4_RefCounter; class e4_DLL e4_StorageImpl; class e4_DLL e4_NodeImpl; class e4_DLL e4_VertexImpl; class e4_DLL e4_RefCount; class e4_DLL e4_Storage; class e4_DLL e4_Node; class e4_DLL e4_Vertex; class e4_DLL e4_StorageVisitor; class e4_DLL e4_VertexVisitor; class e4_DLL e4_NodeVisitor; class e4_DLL e4_Cache; class e4_DLL e4_CommonUniqueID; class e4_DLL e4_NodeUniqueID; class e4_DLL e4_VertexUniqueID; /* * Forward declaration of e4_Value. */ struct e4_Value; /* * Enumerate the various kinds of reference counted entities: * * E4_RKINVALID Illegal value. * E4_RKSTORAGE This instance is a storage. * E4_RKNODE This instance is a node. * E4_RKVERTEX This instance is a vertex. */ typedef enum e4_RefKind { E4_RKINVALID = -1, E4_RKSTORAGE = 0, E4_RKNODE = 2, E4_RKVERTEX = 3 } e4_RefKind; /* * The various storage permissions: * * E4_SPMODIFY Allows read-write access to data contained * in the storage. * E4_SPCOMMIT Allows commits on this storage to make modifications * persistent. * E4_SPINITIALIZE Allows creation of the necessary data structures in * a new storage. * E4_SPUPDATEFORMAT Allows update of an out of date storage format in * existing storages. * E4_SPCOPYTO Allows copying from other storages to this one. * E4_SPCOPYFROM Allows copying from this storage to others. */ #define E4_SPMODIFY (1<<0) #define E4_SPCOPYTO (1<<1) #define E4_SPCOPYFROM (1<<2) #define E4_SPCOMMIT (1<<3) #define E4_SPINITIALIZE (1<<4) #define E4_SPUPDATEFORMAT (1<<5) /* * This mask defines the permission bits set by default. */ #define E4_SPDEFAULTMASK \ (E4_SPMODIFY | E4_SPCOPYTO | E4_SPCOPYFROM | E4_SPCOMMIT | \ E4_SPINITIALIZE | E4_SPUPDATEFORMAT) /* * Enumerate the various vertex types: * * E4_VTUNKNOWN Illegal value. * E4_VTNODE This vertex contains a node. * E4_VTINT This vertex contains a 32-bit integer. * E4_VTDOUBLE This vertex contains a 64-bit floating point number. * E4_VTSTRING This vertex contains a NULL-terminated string. * E4_VTBINARY This vertex contains a binary unstructured value. */ typedef enum e4_VertexType { E4_VTUNKNOWN = -1, E4_VTNODE = 0, E4_VTINT = 1, E4_VTDOUBLE = 2, E4_VTSTRING = 3, E4_VTBINARY = 4, E4_VTLASTVERTEXTYPE = 5 } e4_VertexType; /* * The following enumeration describes how vertices are moved from * another node into this node. The argument determines how the * vertex is inserted into this node: * * E4_IONONE Illegal value. * E4_IOAT Insert at numeric position (zero based). * E4_IOFIRST Insert as zeroth vertex. * E4_IOLAST Insert as last vertex. * E4_IOBEFORE Insert before another named vertex. * E4_IOAFTER Insert after another named vertex. */ typedef enum e4_InsertOrder { E4_IONONE = 0, E4_IOAT = 1, E4_IOFIRST = 2, E4_IOLAST = 3, E4_IOBEFORE = 4, E4_IOAFTER = 5, E4_IOLASTINSERTORDER = 6 } e4_InsertOrder; /* * The following enumeration describes the different methods of * operation for an e4_Visitor instance: * * E4_VMUNKNOWN Illegal value. * E4_VMSTORAGE Visit every vertex in a storage in some random order. * E4_VMNODE Visit every vertex in a node in rank order. * E4_VMNODERANDOM Visit every vertex in a node in some random order. * E4_VMPARENT Visit vertices having a given node as their value * (i.e. vertices pointing at this node). */ typedef enum e4_VisitMethod { E4_VMUNKNOWN = 0, E4_VMSTORAGE = 1, E4_VMNODE = 2, E4_VMNODERANDOM = 3, E4_VMPARENT = 4, E4_VMLASTMETHOD = 5 } e4_VisitMethod; /* * The following enumeration describes the different choices whether to * visit detached entities, attached entities or both. */ typedef enum e4_DetachChoice { E4_DCDETACHED = 0, E4_DCATTACHED = 1, E4_DCBOTH = 2 } e4_DetachChoice; /* * The following bit fields define different filters to apply to exclude * vertices from being visited. These bit fields can be ORed together to * yield more complex filters. */ #define E4_VFNONE 0 /* Always visit. */ #define E4_VFNAME (1 << 0) /* Visit only if name equals. */ #define E4_VFTYPE (1 << 1) /* Visit only if type equals. */ /* * This structure is used to pass a value to/from an untyped vertex * access function. */ typedef struct e4_Binary { int nbytes; /* How big is the value? */ void *bytes; /* The value itself. */ } e4_Binary; /* * A way to transmit arbitrary values: */ typedef struct e4_ValueImpl { e4_VertexType vertexType; /* Type of the value being passed. */ union { e4_NodeImpl *n; int i; double d; char *s; e4_Binary b; } u; } e4_ValueImpl; /* * The following enum describes the various elements of a storage, used * to retrieve statistics for each element usage. */ typedef enum e4_Space { E4_SPNODE = 0, E4_SPVERTEX = 1, E4_SPNAME = 2, E4_SPSTRING = 3, E4_SPINT = 4, E4_SPDOUBLE = 5, E4_SPBINARY = 6, E4_SPLAST = 7 } e4_Space; /* * The following enum describes the different statistics collected for * each space. Some storage drivers may not collect all these statistics. */ typedef enum e4_SpaceStat { E4_SSUSED = 0, E4_SSAVAIL = 1, E4_SSFREED = 2, E4_SSALLOC = 3, E4_SSLAST = 4 } e4_SpaceStat; /* * These constants define the kinds of predefined callbacks supported by * e4Graph. Other callbacks (upto value 31) can be defined by user programs. */ #define E4_ECADDNODE (1<<0) /* A node was added to the storage. */ #define E4_ECDETNODE (1<<1) /* A node became detached. */ #define E4_ECATTNODE (1<<2) /* A node became attached. */ #define E4_ECMODNODE (1<<3) /* A node was modified. */ #define E4_ECADDVERTEX (1<<4) /* A vertex was added to the storage. */ #define E4_ECDETVERTEX (1<<5) /* A vertex became detached. */ #define E4_ECATTVERTEX (1<<6) /* A vertex became attached. */ #define E4_ECMODVERTEX (1<<7) /* A vertex was modified. */ #define E4_ECCHANGESTG (1<<8) /* Storage stable status changed. */ #define E4_ECOPENSTG (1<<9) /* Storage was opened. */ #define E4_ECCOPYTOSTG (1<<10) /* Storage was copied into. */ #define E4_ECCOPYFRMSTG (1<<11) /* Storage was copied from. */ #define E4_ECSETSTGROOT (1<<12) /* The storage's root node was set to some * other node. */ #define E4_ECCOMMITSTG (1<<13) /* The storage was committed. */ /* * This bitmask defines the events that change a storage. */ #define E4_ECMODSTORAGE \ (E4_ECADDNODE | E4_ECDETNODE | E4_ECATTNODE | E4_ECMODNODE | \ E4_ECADDVERTEX | E4_ECDETVERTEX | E4_ECATTVERTEX | E4_ECMODVERTEX | \ E4_ECCOPYTOSTG | E4_ECSETSTGROOT) /* * These constants define the range of possible values for user defined * event codes: */ #define E4_FIRSTUSERDEFINEDEVENTCODE 14 #define E4_LASTUSERDEFINEDEVENTCODE 31 /* * The e4_RefCount class: */ class e4_DLL e4_RefCount { protected: /* * The "impl" field contains the reference to the actual referenced * implementation instance. */ e4_RefCounter *impl; public: /* * Default constructor: */ e4_RefCount(); /* * Copying constructor: */ e4_RefCount(const e4_RefCount &referrer); /* * Assignment operator: */ e4_RefCount & operator=(const e4_RefCount &referrer); /* * Constructor with value assignd to implementation. */ e4_RefCount(e4_RefCounter *ip); /* * Destructor: */ virtual ~e4_RefCount(); /* * Returns the current refcount if the impl field is valid, or * -1 if not. */ int RefCount() const; /* * Is this instance valid? */ bool IsValid() const; /* * Return an identifier for programmatic type identification for * this instance. */ virtual e4_RefKind Kind() const; /* * Comparison operators. */ bool operator==(const e4_RefCount &compared) const; bool operator!=(const e4_RefCount &compared) const; /* * This operation returns an integer that is guaranteed to be unique * while "impl" is valid. It may be different each time the underlying * "impl" is instantiated. */ inline long GetTemporaryUID() { return (long) impl; } /* * These operations manipulate user-level data attached to each instance. */ void SetTransientUserData(void *data) const; void *GetTransientUserData() const; }; /* * This section dealing with callbacks MUST appear after the definition * of e4_RefCount and before the definition of e4_Storage, because it uses * e4_RefCount and is used by e4_Storage. */ /* * This enumeration defines the reasons for an E4_ECMODNODE event: */ typedef enum e4_ModNodeEventReason { E4_ERMNADDVERTEX = 0, /* A vertex was added to a node. */ E4_ERMNDETVERTEX = 1, /* A vertex was detached frm a node. */ E4_ERMNRENVERTEX = 2, /* A vertex was renamed in a node. */ E4_ERMNMOVVERTEX = 3, /* A vertex was moved in this node. */ E4_ERMNINSVERTEX = 4, /* A vertex was moved into * this node. */ E4_ERMNMODUSERDATA = 5 /* The user data for the node was * modified. */ } e4_ModNodeEventReason; /* * This enumeration defines the reasons for an E4_CBMODVERTEX event: */ typedef enum e4_ModVertexEventReason { E4_ERMVMODVALUE = 0, /* The value was modified. */ E4_ERMVRENAME = 1, /* The vertex was renamed. */ E4_ERMVREPARENT = 2, /* The vertex was moved. */ E4_ERMVDETVERTEX = 3, /* The vertex was detached. */ E4_ERMVMODUSERDATA = 4 /* The vertex user data was * modified. */ } e4_ModVertexEventReason; /* * Callback function typedef. */ typedef void (*e4_CallbackFunction)(void *clientData, const e4_RefCount &r, void *csdata); /* * The e4_Storage class: */ class e4_DLL e4_Storage : public e4_RefCount { public: /* * Static function to return version string for e4Graph. */ static const char *version(); /* * Numeric version numbers: */ static int major_version(); static int minor_version(); static e4_ReleaseStatus release_status(); static int release_iteration(); /* * Static function to return a version string for a specific storage. */ static const char *storage_version(const char *fname, const char *drivername); /* * Retrieve numeric version numbers for a storage. */ static bool storage_version_info(const char *fname, const char *drivername, int &majvp, int &minvp, e4_ReleaseStatus &rsp, int &rip); /* * Default constructor: */ e4_Storage(); /* * Copying constructor: */ e4_Storage(const e4_Storage &referrer); /* * Copying constructor thats given an e4_RefCount. */ e4_Storage(const e4_RefCount &referrer); /* * Assignment operator: */ e4_Storage & operator=(const e4_Storage &referrer); /* * No destructor is defined so the e4_RefCount destructor will be used. */ /* * Constructor that chooses a concrete representation for the * underlying implementation. */ e4_Storage(const char *name, const char *drivername); /* * Constructor that lets the user set state for the new storage * at construction time. */ e4_Storage(const char *name, const char *drivername, int state); /* * Constructor that lets the user set state and permissions. */ e4_Storage(const char *name, const char *drivername, int state, int perms); /* * State bits manipulation. */ int SetState(int statemask) const; int GetState() const; /* * Retrieve the storage permissions. The permissions can only * be set at construction time. */ int GetPermissions() const; /* * Commit now. */ bool Commit() const; /* * Copy the content (e4Graph related only) of this storage to another * storage. */ bool CopyTo(e4_Storage otherStorage, bool forceCommit) const; /* * Delete the underlying physical storage. */ bool Delete(); /* * Get and set the root node. */ bool GetRootNode(e4_Node &n) const; bool SetRootNode(e4_Node n) const; /* * Given a unique ID, obtain the node or vertex denoted * by that ID. */ bool GetNodeFromID(e4_NodeUniqueID nid, e4_Node &n) const; bool GetVertexFromID(e4_VertexUniqueID id, e4_Vertex &v) const; /* * Is this storage stable? */ bool IsStable() const; /* * Mark the storage as unstable (it needs to be committed). */ void MarkUnstable() const; /* * Get the name and driver ID for this storage. */ const char *GetName() const; const char *GetDriver() const; /* * Create detached entities within this storage: */ bool CreateDetachedNode(e4_Node &n) const; bool CreateDetachedVertex(const char *nm, e4_Node n, e4_Vertex &v) const; bool CreateDetachedVertex(const char *nm, int i, e4_Vertex &v) const; bool CreateDetachedVertex(const char *nm, double d, e4_Vertex &v) const; bool CreateDetachedVertex(const char *nm, const char *s, e4_Vertex &v) const; bool CreateDetachedVertex(const char *nm, const void *b, int nb, e4_Vertex &v) const; bool CreateDetachedVertex(const char *nm, const e4_Value &vv, e4_Vertex &v) const; /* * Get a value for a statistic being collected for this storage. */ bool GetStatistic(e4_Space sp, e4_SpaceStat st, int &v) const; /* * Do a GC. */ void DoGC() const; /* * Is a GC needed? */ bool NeedsGC() const; /* * Event management: add or delete callbacks, cause events. * * User applications cannot cause events for event codes that are * predefined by e4Graph. Only e4Graph itself can cause these events. * Attempting to do so will cause CauseEvent to return false. User * applications should use CauseEvent to cause events only for user * defined event codes. */ bool DeclareCallback(int eventCode, e4_CallbackFunction fn, void *clientData); bool DeleteCallback(int eventCode, e4_CallbackFunction fn, void *clientData); bool CauseEvent(int eventCode, const e4_RefCount &r, void *csdata); bool CauseEvent(int eventCode, const e4_RefCount &r, void *csdata, int ×tamp); /* * Timestamp mechanism: timestamps are monotonously increasing non-negative * integers denoting the "time" at which specific events occur. All * predefined events and user defined events are captured by the internals * of e4Graph. This mechanism records and retrieves the timestamps for the * occurrence of these events. */ int GetTimeStamp() const; int GetTimeStampFor(int eventmask) const; bool HasOccurredSince(int timestamp, int eventmask) const; /* * Facility for defining new kinds of event codes. These event codes * are defined for *all* storages; there is no facility for defining * storage-specific event codes. * * Applications should not rely on the specific value returned in * eventcode by DefineEventCode. This value may change from one * invocation to the next. It is only intended to be used as an * identifier for calls to DeclareCallback, DeleteCallback and * CauseEvent, above. * * Applications cannot undefine event codes that are predefined by e4Graph. * Trying to do so will cause UndefineEventCode to return false. */ static bool DefineEventCode(int &eventcode); static bool UndefineEventCode(int eventcode); static bool IsEventCodeDefined(int eventcode); /* * Get the kind identifier for an instance of this type: */ virtual e4_RefKind Kind() const; protected: /* * These methods are for use by classes e4_Node, e4_Vertex, * e4_StorageVisitor, e4_VertexVisitor, e4_NodeVisitor, and e4_Cache * only. */ friend class e4_Node; friend class e4_Vertex; friend class e4_StorageVisitor; friend class e4_VertexVisitor; friend class e4_NodeVisitor; friend class e4_StorageImpl; /* * Constructor which assigns a value to the implementation field: */ e4_Storage(e4_StorageImpl *ip); /* * Get the next storage after this one in an implementation dependent * order that visits all currently open storages. */ bool FindNextStorage(e4_Storage &ss) const; /* * Get the next vertex after a vertex identified by a unique ID, * using a search method specified by "vm" and "vf". These are * defined in e4common.h. */ bool FindNextVertex(int vertexID, e4_VisitMethod vm, int vf, int nameId, int nodeID, int parentID, e4_VertexType typeID, e4_DetachChoice dc, e4_Vertex &f) const; /* * Find the next node after a node identified by a unique ID. */ bool FindNextNode(int nodeID, e4_DetachChoice dc, e4_Node &n) const; /* * Intern a name. */ int InternName(const char *nm) const; /* * Get a node given its node ID: */ e4_NodeImpl *GetNode(int nodeID) const; /* * Get the name of a vertex given the name ID. */ const char *GetName(int nameID) const; /* * Get the storage implementation from this storage: */ e4_StorageImpl *GetStorageImpl() const; }; /* * The e4_Node class: */ class e4_DLL e4_Node : public e4_RefCount { public: /* * Default constructor: */ e4_Node(); /* * Copying constructor: */ e4_Node(const e4_Node &referrer); /* * Copying constructor that's given an e4_RefCount: */ e4_Node(const e4_RefCount &referrer); /* * Assignment operator: */ e4_Node & operator=(const e4_Node &referrer); /* * No destructor is defined so the e4_RefCount destructor will be used. */ /* * How many vertices are there in this node? */ int VertexCount() const; /* * How many vertices in this node have the given name, type or value? */ int VertexCountWithName(const char *name) const; int VertexCountWithType(e4_VertexType typeID) const; int VertexCountWithValue(const e4_Value &v) const; /* * Operations to set data into existing vertices in this node. */ bool SetNthVertex(const char *nm, int nth, int i) const; bool SetNthVertex(const char *nm, int nth, double f) const; bool SetNthVertex(const char *nm, int nth, const char *s) const; bool SetNthVertex(const char *nm, int nth, const void *b, int nb) const; bool SetNthVertex(const char *nm, int nth, e4_Node n) const; bool SetNthVertex(const char *nm, int nth, const e4_Value &v) const; bool SetNthNode(const char *nm, int nth, e4_Node &n) const; inline bool SetVertex(const char *nm, int i) const { return SetNthVertex(nm, 1, i); } inline bool SetVertex(const char *nm, double f) const { return SetNthVertex(nm, 1, f); } inline bool SetVertex(const char *nm, const char *s) const { return SetNthVertex(nm, 1, s); } inline bool SetVertex(const char *nm, const void *b, int nb) const { return SetNthVertex(nm, 1, b, nb); } inline bool SetVertex(const char *nm, e4_Node n) const { return SetNthVertex(nm, 1, n); } inline bool SetVertex(const char *nm, const e4_Value &v) const { return SetNthVertex(nm, 1, v); } inline bool SetNode(const char *nm, e4_Node &n) const { return SetNthNode(nm, 1, n); } /* * Set the value of an existing vertex in this node identified by rank. */ bool SetVertexByRank(int rank, int i) const; bool SetVertexByRank(int rank, double f) const; bool SetVertexByRank(int rank, const char *s) const; bool SetVertexByRank(int rank, const void *b, int nb) const; bool SetVertexByRank(int rank, e4_Node n) const; bool SetVertexByRank(int rank, const e4_Value &v) const; bool SetNodeByRank(int rank, e4_Node &n) const; /* * Add a new vertex to this node according to the rank and order arguments. * The rank argument is in-out; on the way in, in combination with the * order argument, it determines where in the node the new vertex is * created. On the way out, it returns the rank of the newly created * vertex. Upon success, these operations return true. If an error occurred * these operations return false. */ bool AddVertex(const char *nm, e4_InsertOrder order, int &rank, int value) const; bool AddVertex(const char *nm, e4_InsertOrder order, int &rank, double f) const; bool AddVertex(const char *nm, e4_InsertOrder order, int &rank, const char *s) const; bool AddVertex(const char *nm, e4_InsertOrder order, int &rank, const void *b, int nb) const; bool AddVertex(const char *nm, e4_InsertOrder order, int &rank, e4_Node n) const; bool AddVertex(const char *nm, e4_InsertOrder order, int &rank, const e4_Value &v) const; bool AddNode(const char *nm, e4_InsertOrder order, int &rank, e4_Node &n) const; /* * Add a new vertex and also return an e4_Vertex for the new vertex. * This is much more efficient than AddVertex followed by GetVertexRef. */ bool AddVertexRef(const char *nm, e4_InsertOrder order, int &rank, int ii, e4_Vertex &f) const; bool AddVertexRef(const char *nm, e4_InsertOrder order, int &rank, double ff, e4_Vertex &f) const; bool AddVertexRef(const char *nm, e4_InsertOrder order, int &rank, const char *ss, e4_Vertex &f) const; bool AddVertexRef(const char *nm, e4_InsertOrder order, int &rank, const void *b, int nb, e4_Vertex &f) const; bool AddVertexRef(const char *nm, e4_InsertOrder order, int &rank, e4_Node n, e4_Vertex &f) const; bool AddVertexRef(const char *nm, e4_InsertOrder order, int &rank, const e4_Value &v, e4_Vertex &f) const; bool AddNodeRef(const char *nm, e4_InsertOrder order, int &rank, e4_Node &n, e4_Vertex &f) const; /* * Move a given vertex to a specified position within this node. */ bool MoveVertex(const e4_Vertex &f, e4_InsertOrder order, int rank); /* * Get a value out of a vertex. If the vertex is found then the output * parameter is set, otherwise it is not modified. * * The char * and void * returned are valid only until the next call to * any e4Graph API. If the caller needs to keep access to the value, * copy the value into memory owned by the caller. */ bool GetNthVertex(const char *nm, int nth, e4_Value &v) const; bool GetNthVertex(const char *nm, int nth, e4_Node &n) const; bool GetNthVertex(const char *nm, int nth, int &v) const; bool GetNthVertex(const char *nm, int nth, double &v) const; bool GetNthVertex(const char *nm, int nth, const char *&v) const; bool GetNthVertex(const char *nm, int nth, const void *&v, int &nbv) const; inline bool GetVertex(const char *nm, e4_Value &v) const { return GetNthVertex(nm, 1, v); } inline bool GetVertex(const char *nm, e4_Node &v) const { return GetNthVertex(nm, 1, v); } inline bool GetVertex(const char *nm, int &v) const { return GetNthVertex(nm, 1, v); } inline bool GetVertex(const char *nm, double &v) const { return GetNthVertex(nm, 1, v); } inline bool GetVertex(const char *nm, const char *&s) const { return GetNthVertex(nm, 1, s); } inline bool GetVertex(const char *nm, const void *&v, int &nbv) const { return GetNthVertex(nm, 1, v, nbv); } /* * Get the value of a vertex identified by rank, in this node. */ bool GetVertexByRank(int rank, e4_Value &v) const; bool GetVertexByRank(int rank, e4_Node &n) const; bool GetVertexByRank(int rank, int &v) const; bool GetVertexByRank(int rank, double &v) const; bool GetVertexByRank(int rank, const char *&s) const; bool GetVertexByRank(int rank, const void *&v, int &nbv) const; /* * Detach a vertex. */ bool DetachVertex(const char *nm, int nth) const; inline bool DetachVertex(const char *nm) const { return DetachVertex(nm, 1); } bool DetachVertexByRank(int rank) const; /* * Detach the first vertex whose value is a given child node. */ bool DetachFirstVertexWithNode(e4_Node child) const; /* * Get an e4_Vertex for a vertex identified by name or rank. */ bool GetVertexRef(const char *nm, int nth, e4_Vertex &f) const; inline bool GetVertexRef(const char *nm, e4_Vertex &f) const { return GetVertexRef(nm, 1, f); } bool GetVertexRefByRank(int rank, e4_Vertex &f) const; /* * Get the type of the value stored in a specific vertex. */ e4_VertexType VertexType(const char *nm, int nth) const; inline e4_VertexType VertexType(const char *nm) const { return VertexType(nm, 1); } e4_VertexType VertexTypeByRank(int rank) const; /* * Get the name of a vertex. */ const char *VertexName(int rank) const; /* * Rename a vertex. */ bool RenameVertex(int rank, const char *newName) const; /* * Get the rank of a vertex. */ int VertexRank(const char *nm, int nth) const; inline int VertexRank(const char *nm) const{ return VertexRank(nm, 1); } /* * Does a named vertex exist? */ bool Exists(const char *nm, int nth) const; inline bool Exists(const char *nm) const{ return Exists(nm, 1); } /* * Get a parent node of a node. */ bool GetParent(int nth, e4_Node &p) const; inline bool GetParent(e4_Node &p) const { return GetParent(1, p); } /* * Retrieve the nth vertex in the given parent node p whose value * is this node. */ bool GetVertexRefFromParent(e4_Node p, int nth, e4_Vertex &v) const; /* * Retrieve the nth vertex in the ith parent whose value is this node. */ bool GetVertexRefFromParent(int i, int nth, e4_Vertex &v) const; /* * How many parents does this node have? */ int ParentCount() const; /* * How many vertices contain this node as the value? */ int OccurrenceCount() const; /* * How many times does this node occur as a child in the given node? */ int OccurrenceCount(e4_Node p) const; /* * What is the rank of this parent for this node? */ int ParentRank(e4_Node p) const; /* * A node is the root if it would be the node returned by * s.GetRootNode() on its storage. */ bool IsRoot() const; /* * Get the root node of the storage containing this node. */ bool GetRootNode(e4_Node &rn) const; /* * Get the rank of the ith vertex containing this node in its nth parent * and the name of the ith vertex containing this node in its nth parent. * There are also versions that take the e4_Node for the parent instead * of its parent rank. */ int GetRankInParent(e4_Node p, int ith) const; int GetRankInParent(int nth, int ith) const; inline int GetRankInParent(int nth) const { return GetRankInParent(nth, 1); } inline int GetRankInParent() const { return GetRankInParent(1); } const char *GetNameInParent(e4_Node p, int ith) const; const char *GetNameInParent(int nth, int ith) const; inline const char *GetNameInParent(int nth) const { return GetNameInParent(nth, 1); } inline const char *GetNameInParent() const { return GetNameInParent(1); } /* * Get the storage containing this node. */ bool GetStorage(e4_Storage &s) const; /* * Get a unique ID (unique within the storage containing this node) for * the node. */ bool GetUniqueID(e4_NodeUniqueID &n) const; /* * Detach this node by detaching all vertices for which this node is * the value. */ bool Detach() const; /* * Is this node detached? */ bool IsDetached() const; /* * Return the kind identifier for an instance of this type: */ virtual e4_RefKind Kind() const; /* * Get/Set user data associated with this node. */ bool GetUserData(int &userData) const; bool SetUserData(int userData) const; /* * Get/Set user data for a contained vertex. */ bool GetVertexUserData(const char *name, int &userData) const; bool GetVertexUserData(const char *name, int nth, int &userData) const; bool SetVertexUserData(const char *name, int userData) const; bool SetVertexUserData(const char *name, int nth, int userData) const; bool GetVertexUserDataByRank(int rank, int &userData) const; bool SetVertexUserDataByRank(int rank, int userData) const; /* * Get/Set advisory cache management policy flags: */ int SetAdvisoryCachingPolicy(bool set, int mask) const; int GetAdvisoryCachingPolicy() const; /* * Pre-cache the vertex IDs for all vertices in this node. */ void PreCache() const; protected: /* * These operations are for use by class e4_Storage, e4_Vertex,, e4_Cache, * e4_VertexVisitor, e4_StorageVisitor, and e4_NodeVisitor only: */ friend class e4_Storage; friend class e4_Vertex; friend class e4_StorageVisitor; friend class e4_VertexVisitor; friend class e4_NodeVisitor; friend class e4_StorageImpl; friend class e4_Cache; /* * Constructor which assigns a value to the implementation field: */ e4_Node(e4_NodeImpl *ip); /* * Get the unique ID for this node in a raw (unwrapped) form. */ int GetRawUniqueID() const; }; /* * The e4_Vertex class: */ class e4_DLL e4_Vertex : public e4_RefCount { public: /* * Default constructor: */ e4_Vertex(); /* * Copying constructor: */ e4_Vertex(const e4_Vertex &referrer); /* * Copying constructor that's given an e4_RefCount: */ e4_Vertex(const e4_RefCount &referrer); /* * Assignment operator: */ e4_Vertex & operator=(const e4_Vertex &referrer); /* * No destructor is defined so the e4_RefCount destructor will be used. */ /* * Get the value stored in this vertex. */ bool Get(e4_Value &v) const; bool Get(e4_Node &n) const; bool Get(int &v) const; bool Get(double &v) const; bool Get(const char *&s) const; bool Get(const void *&b, int &nb) const; /* * Set the content of this vertex (and its type) to the value supplied. */ bool Set(int v) const; bool Set(double v) const; bool Set(const char *v) const; bool Set(const void *b, int nb) const; bool Set(e4_Node n) const; bool Set(const e4_Value &v) const; /* * Set the content of this vertex to a new node and return the new node. */ bool SetNode(e4_Node &n) const; /* * Get the rank of this vertex in the node in which it appears. */ int Rank() const; /* * Get the count of how many vertices up to this one in the containing * node have the same name. If this vertex is detached, return -1. */ int CountWithName() const; /* * Get the total count of how many vertices in the node containing * this one have the same name. If this vertex is detached, return -1. */ int TotalCountWithName() const; /* * Get the count of how many vertices up to this one in the containing * node have the same type. If this vertex is detached, return -1. */ int CountWithType() const; /* * Get the total count of how many vertices in the node containing * this one have the same type. If this vertex is detached, return -1. */ int TotalCountWithType() const; /* * Detach this vertex from its containing node. */ bool Detach() const; /* * Is this vertex detached? */ bool IsDetached() const; /* * Return the type of the vertex. */ e4_VertexType Type() const; /* * Return the name of the vertex. */ const char *Name() const; /* * Rename this vertex. */ bool Rename(const char *newname) const; /* * Get a unique (within the storage containing it) ID for this vertex. */ bool GetUniqueID(e4_VertexUniqueID &v) const; /* * Get the root node of the storage containing this vertex. */ bool GetRootNode(e4_Node &rn) const; /* * Get the storage in which this vertex appears. */ bool GetStorage(e4_Storage &ss) const; /* * Get the node in which this vertex appears. */ bool GetNode(e4_Node &nn) const; /* * Move the given vertex into the node containing this vertex at * the indicated insertOrder and offset. If insertOrder is either * E4_IOBEFORE, offset is subtracted from the rank of this vertex * plus one to get the rank at which the given vertex is inserted. * If insertOrder is E4_IOAFTER, offset is added to the rank of * this vertex to get the rank at which the given vertex is inserted. * In these cases, offset must be equal or greater than one. * Otherwise offset is ignored. */ bool MoveVertex(const e4_Vertex &ff, e4_InsertOrder order, int offset) const; /* * Retrieve the next vertex after this one in the node * containing this vertex. */ bool Next(int num, e4_Vertex &ff) const; /* * Retrieve the previous vertex before this one in the node * containing this vertex. */ bool Prev(int num, e4_Vertex &ff) const; /* * Return the kind identifier for an instance of this type: */ virtual e4_RefKind Kind() const; /* * Get/Set user data associated with this vertex. */ bool GetUserData(int &userData) const; bool SetUserData(int userData) const; protected: /* * These operations are for use by class e4_Node, e4_Storage, e4_Cache, * e4_VertexVisitor, e4_StorageVisitor, and e4_NodeVisitor only: */ friend class e4_Node; friend class e4_Storage; friend class e4_StorageVisitor; friend class e4_VertexVisitor; friend class e4_NodeVisitor; friend class e4_StorageImpl; friend class e4_Cache; /* * Constructor which assigns a value to the implementation field: */ e4_Vertex(e4_VertexImpl *ip); /* * Get the unique ID for this vertex in a raw (unwrapped) form. */ int GetRawUniqueID() const; }; /* * Class e4_StorageVisitor */ class e4_DLL e4_StorageVisitor { private: /* * The storage being visited now. */ e4_Storage s; /* * Is this visitor done visiting all the storages? */ bool done; public: /* * Default constructor: */ e4_StorageVisitor(); /* * Copying constructor: */ e4_StorageVisitor(const e4_StorageVisitor &referrer); /* * Assignment operator: */ e4_StorageVisitor & operator=(const e4_StorageVisitor &referrer); /* * Comparison operators: */ bool operator==(const e4_StorageVisitor &compared) const; bool operator!=(const e4_StorageVisitor &compared) const; /* * Destructor: */ virtual ~e4_StorageVisitor(); /* * Is this visitor done visiting all the storages? */ bool IsDone(); /* * Get the current storage being visited: */ bool CurrentStorage(e4_Storage &ss); /* * Get the current storage being visited and advance the * visitor to the next storage. */ bool CurrentStorageAndAdvance(e4_Storage &ss); /* * Get the next storage: */ bool NextStorage(e4_Storage &ss); /* * Advance to the next storage but do not retrieve it: */ bool Advance(); /* * Is this instance valid? */ bool IsValid(); }; /* * Class e4_VertexVisitor: */ class e4_DLL e4_VertexVisitor { private: /* * The storage used by this visitor. */ e4_Storage s; /* * The last vertex returned by the visitor. */ e4_Vertex f; /* * Is this visitor done visiting all vertices in its itinerary? */ bool done; /* * Is this visitor visiting detached vertices, attached vertices, or both? */ e4_DetachChoice detachchoice; /* * The ID of the node whose vertices we will visit. */ int nodeID; /* * The ID of the parent node whose vertices we will visit. */ int parentID; /* * Only vertices with this nameID will be visited. */ int nameID; /* * Only vertices with this type will be visited. */ e4_VertexType typeID; /* * The method by which vertices are visited. */ e4_VisitMethod vm; /* * Vertices to be visited are chosen by this visit filter. */ int vf; public: /* * Default constructor: */ e4_VertexVisitor(); /* * Copying constructor: */ e4_VertexVisitor(const e4_VertexVisitor &referrer); /* * Assignment operator: */ e4_VertexVisitor & operator=(const e4_VertexVisitor &referrer); /* * Comparison operators: */ bool operator==(const e4_VertexVisitor &compared) const; bool operator!=(const e4_VertexVisitor &compared) const; /* * Constructors which initialize the visitor from a node. */ e4_VertexVisitor(const e4_Node &n); e4_VertexVisitor(const e4_Node &n, const char *nm, e4_VertexType ft); e4_VertexVisitor(const e4_Node &child, const e4_Node &parent, e4_DetachChoice dc); e4_VertexVisitor(const e4_Node &child, const e4_Node &parent, e4_DetachChoice dc, const char *nm); /* * Constructors which initialize the visitor from a vertex. */ e4_VertexVisitor(const e4_Vertex &ff); e4_VertexVisitor(const e4_Vertex &ff, bool useVertexName, bool useVertexType); e4_VertexVisitor(const e4_Vertex &ff, bool useVertexName, bool useVertexType, e4_VisitMethod vmvm); /* * Constructors that initialize the visitor from a storage. */ e4_VertexVisitor(const e4_Storage &s); e4_VertexVisitor(const e4_Storage &s, e4_DetachChoice dc); e4_VertexVisitor(const e4_Storage &s, const char *nm, e4_VertexType ft); e4_VertexVisitor(const e4_Storage &s, e4_DetachChoice dc, const char *nm, e4_VertexType vt); /* * Destructor: */ virtual ~e4_VertexVisitor(); /* * Is this visitor done visiting all the vertices in its itinerary? */ bool IsDone(); /* * Get the next vertex from the visitor. */ bool NextVertex(e4_Vertex &ff); /* * Advance to the next vertex but do not retrieve it: */ bool Advance(); /* * Get the current vertex. */ bool CurrentVertex(e4_Vertex &ff); /* * Retrieve the current vertex and advance to the next one. */ bool CurrentVertexAndAdvance(e4_Vertex &ff); /* * Reset the visitor to visit vertices that have a given node * as their value. */ bool SetParentVertex(const e4_Node &child, const e4_Node &parent, e4_DetachChoice dc, const char *nm); /* * Reset the visitor to a given vertex. */ bool SetVertex(const e4_Vertex &ff); bool SetVertex(const e4_Vertex &ff, bool useVertexName, bool useVertexType); bool SetVertex(const e4_Vertex &ff, bool useVertexName, bool useVertexType, e4_VisitMethod vmvm); /* * Reset the visitor to start at the first vertex of the given node. */ bool SetNode(const e4_Node &nn); bool SetNode(const e4_Node &nn, const char *nm, e4_VertexType ft); /* * Reset the visitor to visit all vertices in a storage. */ bool SetStorage(const e4_Storage &ss); bool SetStorage(const e4_Storage &ss, e4_DetachChoice dc); bool SetStorage(const e4_Storage &ss, const char *nm, e4_VertexType ft); bool SetStorage(const e4_Storage &ss, const char *nm, e4_VertexType ft, e4_DetachChoice dc); /* * Is this instance valid? */ bool IsValid(); /* * Query methods: */ inline e4_VisitMethod VisitMethod() const {return vm;} inline int VisitFilter() const {return vf;} inline bool StorageVisited(e4_Storage &ss) const { if (s.IsValid()) { ss = s; return true; } return false; } inline bool VertexVisited(e4_Vertex &ff) const { if (s.IsValid() && f.IsValid()) { ff = f; return true; } return false; } inline e4_VertexType TypeFilter() const {return typeID;} const char *NameFilter() const; bool NodeVisited(e4_Node &n) const; }; /* * class e4_NodeVisitor: */ class e4_DLL e4_NodeVisitor { private: /* * The storage used by this visitor. */ e4_Storage s; /* * The last node returned by the visitor. */ e4_Node n; /* * Is this visitor done visiting all the nodes in this storage? */ bool done; /* * Is this visitor visiting detached nodes, attached nodes or both? * (false)? */ e4_DetachChoice detachchoice; public: /* * Default constructor: */ e4_NodeVisitor(); /* * Copying constructor: */ e4_NodeVisitor(const e4_NodeVisitor &referrer); /* * Assignment operator: */ e4_NodeVisitor & operator=(const e4_NodeVisitor &referrer); /* * Comparison operators: */ bool operator==(const e4_NodeVisitor &compared) const; bool operator!=(const e4_NodeVisitor &compared) const; /* * Constructors that initialize the visitor from a storage, node, * or vertex. */ e4_NodeVisitor(const e4_Storage &ss); e4_NodeVisitor(const e4_Storage &ss, e4_DetachChoice dc); e4_NodeVisitor(const e4_Node &nn); e4_NodeVisitor(const e4_Vertex &ff); /* * Destructor: */ virtual ~e4_NodeVisitor(); /* * Is this visitor done visiting all the nodes in this storage? */ bool IsDone(); /* * Get the next node from this visitor: */ bool NextNode(e4_Node &nn); /* * Advance to the next node but do not retrieve it: */ bool Advance(); /* * Get the current node. */ bool CurrentNode(e4_Node &nn); /* * Get the current node and advance the visitor to the next node. */ bool CurrentNodeAndAdvance(e4_Node &nn); /* * Reset the visitor from a given storage, node, or vertex. */ bool SetStorage(const e4_Storage &ss); bool SetStorage(const e4_Storage &ss, e4_DetachChoice dc); bool SetNode(const e4_Node &nn); bool SetVertex(const e4_Vertex &ff); /* * Is this visitor valid? */ bool IsValid(); }; /* * A way to transmit arbitrary values: */ typedef struct e4_Value { e4_VertexType vertexType; /* Type of the value being passed. */ e4_Node n; union { int i; double d; char *s; e4_Binary b; } u; } e4_Value; /* * Global constant instances of e4_RefCount, e4_Storage, e4_Node * and e4_Vertex that are guaranteed to be invalid. You can assign these * to a variable of the appropriate type to ensure that the reference * previously stored in that variable is discarded. Especially useful for * removing remaining references in heap-allocated structures. */ extern e4_DLL const e4_RefCount invalidRefCount; extern e4_DLL const e4_Storage invalidStorage; extern e4_DLL const e4_Node invalidNode; extern e4_DLL const e4_Vertex invalidVertex; /* * The parts common to all wrappers: */ class e4_DLL e4_CommonUniqueID { private: /* * The wrapped ID and SP values: */ int ID; int SP; public: /* * Default constructor: */ e4_CommonUniqueID(); /* * Copying constructor: */ e4_CommonUniqueID(const e4_CommonUniqueID &referrer); /* * Constructor that assigns a unique ID to the wrapper: */ e4_CommonUniqueID(int uid, int sp); /* * Assignment operator: */ e4_CommonUniqueID & operator=(const e4_CommonUniqueID &referrer); /* * Destructor: */ virtual ~e4_CommonUniqueID(); /* * Get and assign the ID, SP fields. */ inline int GetID() const {return ID;} inline void SetID(int id) {ID = id;} inline int GetSP() const {return SP;} inline void SetSP(int sp) {SP = sp;} /* * Comparison operators: */ bool operator==(const e4_CommonUniqueID &compared) const; bool operator!=(const e4_CommonUniqueID &compared) const; /* * Is this unique ID wrapper assigned a value? */ inline bool IsAssigned() const { return ((ID == E4_INVALIDUNIQUEID) || (SP == 0))? false : true; } }; /* * Wrapper for unique ID derived from an e4_Node. */ class e4_DLL e4_NodeUniqueID : public e4_CommonUniqueID { public: /* * Default constructor: */ e4_NodeUniqueID(); /* * Copying constructor: */ e4_NodeUniqueID(const e4_NodeUniqueID &referrer); /* * Constructor that assigns a value. */ e4_NodeUniqueID(int nid, int sp); /* * Assignment operator: */ e4_NodeUniqueID & operator=(const e4_NodeUniqueID &referrer); /* * Comparison operators: */ bool operator==(const e4_NodeUniqueID &compared) const; bool operator!=(const e4_NodeUniqueID &compared) const; /* * Extract the value. */ inline operator int() const {return GetID();} /* * Extract the value. */ inline int GetUniqueID() const {return GetID();} /* * Set the value. */ inline void SetUniqueID(int nid, e4_Storage s) { if (!s.IsValid()) { return; } SetID(nid); SetSP(s.GetTemporaryUID()); } }; /* * Wrapper for unique ID derived from an e4_Vertex. */ class e4_DLL e4_VertexUniqueID : public e4_CommonUniqueID { public: /* * Default constructor: */ e4_VertexUniqueID(); /* * Copying constructor: */ e4_VertexUniqueID(const e4_VertexUniqueID &referrer); /* * Constructor that assigns a value. */ e4_VertexUniqueID(int vid, int sp); /* * Assignment operator: */ e4_VertexUniqueID & operator=(const e4_VertexUniqueID &referrer); /* * Comparison operators: */ bool operator==(const e4_VertexUniqueID &compared) const; bool operator!=(const e4_VertexUniqueID &compared) const; /* * Extract the value. */ inline operator int() const {return GetID();} /* * Extract the value. */ inline int GetUniqueID() const {return GetID();} /* * Set the value. */ inline void SetUniqueID(int nid, e4_Storage s) { if (!s.IsValid()) { return; } SetID(nid); SetSP(s.GetTemporaryUID()); } }; /*********************************************************************** * * Dynamic string API: * *********************************************************************** */ /* * How big is the static space for dynamic strings? */ #define E4_DSTRING_STATIC_SIZE 200 /* * The DString class: */ class e4_DLL e4_DString { private: /* * The string itself. */ char *buf; /* * The static space. */ char staticSpace[E4_DSTRING_STATIC_SIZE + 1]; /* * How much space is available? */ int spaceAvailable; /* * And how long is the current value of the string? */ int length; public: /* * Constructor: */ e4_DString(); /* * Destructor: */ virtual ~e4_DString(); /* * Append a string to this DString. */ void Append(const char *str, int slen); /* * Get the current value of the string. */ char *Get() const; /* * Get a copy of the current value of the string. */ char *GetCopy() const; /* * Get the length of the string. */ int Length() const; /* * Set the length of the string. */ int SetLength(int newlength); /* * Reset the instance to its original state (empty contents, * static buffer). */ void Reset(); }; /*********************************************************************** * * Hash table API: * *********************************************************************** */ /* * Forward declaration of E4_HashTable. Needed by some C++ compilers * to prevent errors when the forward reference to E4_HashTable is * encountered in the E4_HashEntry structure. */ struct e4_HashTable; /* * Structure definition for an entry in a hash table. */ typedef struct e4_HashEntry { struct e4_HashEntry *nextPtr; /* Pointer to next entry in this * hash bucket, or NULL for end of * chain. */ struct e4_HashTable *tablePtr; /* Ptr to table containing entry. */ struct e4_HashEntry **bucketPtr; /* Pointer to bucket that points to * first entry in this entry's chain: * used for deleting the entry. */ void *clientData; /* Application stores something here * with e4_SetHashValue. */ union { /* Key has one of these forms: */ char *oneWordValue; /* One-word value for key. */ int words[1]; /* Multiple integer words for key. * The actual size will be as large * as necessary for this table's * keys. */ char string[4]; /* String for key. The actual size * will be as large as needed to hold * the key. */ } key; /* MUST BE LAST FIELD IN RECORD!! */ } e4_HashEntry; /* * Structure definition for a hash table. Must be in e4.h so clients * can allocate space for these structures, but clients should never * access any fields in this structure. */ #define E4_SMALL_HASH_TABLE 4 typedef struct e4_HashTable { e4_HashEntry **buckets; /* Pointer to bucket array. Each * element points to first entry in * bucket's hash chain, or NULL. */ e4_HashEntry *staticBuckets[E4_SMALL_HASH_TABLE]; /* Bucket array used for small tables * (to avoid mallocs and frees). */ int numBuckets; /* Total number of buckets allocated * at **bucketPtr. */ int numEntries; /* Total number of entries present * in table. */ int rebuildSize; /* Enlarge table when numEntries gets * to be this large. */ int downShift; /* Shift count used in hashing * function. Designed to use high- * order bits of randomized keys. */ int mask; /* Mask value used in hashing * function. */ int keyType; /* Type of keys used in this table. * It's either E4_STRING_KEY, * E4_ONE_WORD_KEY, or an integer * giving the number of ints that * is the size of the key. */ e4_HashEntry *(*findProc) (struct e4_HashTable *tablePtr, const char *key); e4_HashEntry *(*createProc) (struct e4_HashTable *tablePtr, const char *key, int *newPtr); } e4_HashTable; /* * Structure definition for information used to keep track of searches * through hash tables: */ typedef struct e4_HashSearch { e4_HashTable *tablePtr; /* Table being searched. */ int nextIndex; /* Index of next bucket to be * enumerated after present one. */ e4_HashEntry *nextEntryPtr; /* Next entry to be enumerated in the * the current bucket. */ } e4_HashSearch; /* * Acceptable key types for hash tables: */ #define E4_STRING_KEY 0 #define E4_ONE_WORD_KEY 1 #define E4_TWO_WORDS_KEY 2 /* * Macros for clients to use to access fields of hash entries: */ #define E4_GETHASHVALUE(h) ((h)->clientData) #define E4_SETHASHVALUE(h, value) ((h)->clientData = (void *) (value)) #define E4_GETHASHKEY(tablePtr, h) \ ((char *) (((tablePtr)->keyType == E4_ONE_WORD_KEY) \ ? (h)->key.oneWordValue \ : (h)->key.string)) /* * Macros to use for clients to use to invoke find and create procedures * for hash tables: */ #define E4_FINDHASHENTRY(tablePtr, key) \ (*((tablePtr)->findProc))(tablePtr, key) #define E4_CREATEHASHENTRY(tablePtr, key, newPtr) \ (*((tablePtr)->createProc))(tablePtr, key, newPtr) /* * Function entry points: */ extern e4_DLL void e4_DeleteHashEntry (e4_HashEntry *entryPtr); extern e4_DLL void e4_DeleteHashTable (e4_HashTable *tablePtr); extern e4_DLL e4_HashEntry * e4_FirstHashEntry (e4_HashTable *tablePtr, e4_HashSearch *searchPtr); extern e4_DLL e4_HashEntry * e4_NextHashEntry (e4_HashSearch *searchPtr); extern e4_DLL e4_HashTable * e4_NewHashTable (int keyType); #ifdef NOTDEF /* * The generic cache facility: * * This facility allows user applications to associate a sizeof(void *) value * with each e4_Storage, e4_Node and e4_Vertex. It provides operations for * storing, retrieving and deleting the association. */ class e4_DLL e4_Cache { private: /* * These hash tables contain the data associated with instances of * e4_Graph entities. */ e4_HashTable *tblStorages; e4_HashTable *tblNodes; e4_HashTable *tblVertices; public: /* * Constructor: */ e4_Cache(); /* * Destructor: */ ~e4_Cache(); /* * Operations to create, retrieve and delete associations: */ void Put(e4_Storage s, void *cd); void Put(e4_Node n, void *cd); void Put(e4_Vertex v, void *cd); void *Get(e4_Storage s); void *Get(e4_Node n); void *Get(e4_Vertex v); void Del(e4_Storage s); void Del(e4_Node n); void Del(e4_Vertex v); /* * Delete all associations for entities that are contained within the * given storage. */ void DelAll(e4_Storage s); /* * Prune all entries for which the passed-in predicate returns * non-zero. */ void PruneStorages(int (*fn)(void *)); void PruneNodes(int (*fn)(void *)); void PruneVertices(int (*fn)(void *)); /* * Operations to retrieve the caches for each data type. */ e4_HashTable *GetStorageCache(); e4_HashTable *GetNodeCache(); e4_HashTable *GetVertexCache(); }; #endif #endif /* __E4_GRAPH_H__ */