The e4_Vertex Class

The e4_Vertex class provides the abstraction of a vertex originating from a node. A vertex is associated with a node, its originating node. The e4_Vertex class provides a method to obtain an instance of e4_Node that represents the originating node. Vertices can also be detached, in which case they are not associated with any originating node. A vertex may become detached as a result of some operation on its containing storage, such as detaching a vertex or a node. It is also possible to create detached vertices directly using the CreateDetachedVertex methods on class e4_Storage.

Vertices are identified by name and instance count or by rank within the originating node. Each vertex stores a value of a specific type, a node, an integer, a 64-bit floating point number, a NULL terminated string, or a binary uninterpreted value of variable size. It is usually orders of magnitude more efficient to manipulate the attributes of a vertex through an instance of e4_Vertex rather than indirectly through the instance of e4_Node that represents the node containing the vertex.

The underlying representation of vertices is reference counted. When the last instance of e4_Vertex referring to a vertex is deleted, the reference count for the underlying vertex representation reaches zero and its memory is freed automatically. Note that changes to the attributes of a vertex are written out to persistent storage only when the storage is committed.

Instances of e4_Vertex are not constructed directly by a user program. Instead, they are obtained as the output of various operations on other elements. For example:

e4_Node n;
e4_Vertex v;
...
if (!n.GetVertexRef("joe", 3, v)) {
    cerr << "Third vertex named \"joe\" not found.\n";
}
...
if (!n.GetVertexRefByRank(2, v)) {
    cerr << "This node does not have 2 vertices.\n";
}
If the GetVertexRef operation on n succeeds, v is set to an instance of e4_Vertex representing the third vertex named joe in n. Similarly, if the GetVertexByRank operation on n succeeds, v is set to an instance of e4_Vertex representing the vertex ranked second in n.

The e4_Vertex class provides assignment and comparison operators. When one instance of e4_Vertex is assigned to another, they now refer to the same vertex. The comparison operators allow a user program to determine whether two instances of e4_Vertex refer to the same vertex:

e4_Node n;
e4_Vertex v1, v2, v3, v4;
...
if (!n.GetVertexRef("joe", 2, v1)) {
    cerr << "Second vertex named \"joe\" not found.\";
}
...
if (!n.GetVertexRefByRank(3, v2)) {
    cerr << "This node does not have 3 vertices.\n";
}
...
v3 = v1;
v4 = v2;
if (v1 == v2) {
    if (v3 != v4) {
        cerr << "Something fishy here!\n";
    }
}
The global variable invalidVertex refers to a constant instance of e4_Vertex that is guaranteed to be invalid. You can assign this instance to a local e4_Vertex variable to discard the reference it contains to another vertex, as shown in the following example:
e4_Node n;
e4_Vertex v;
...
if (!n.GetVertexRef("joe", 2, v)) {
    cerr << "Second vertex named \"joe\" not found.\n";
}
...
v = invalidVertex;
if (v.IsValid()) {
    cerr << "Something fishy here!\n";
}
In this example, the assignment of invalidVertex to v causes the reference count for the vertex previously stored in v to drop to zero, and its memory is automatically freed. Note that any changes to the vertex are not written out until the storage containing the vertex is ommitted. Some C++ compilers require you to assign invalidVertex to fields of type e4_Vertex embedded within heap allocated structures before these structures are freed, to ensure that the reference count of vertices referenced by the embedded instances is correct. The IsValid method returns true if the this is an instance of e4_Vertex representing a valid vertex. When the storage containing a vertex is closed, any variables of type e4_Vertex referring to that vertex become invalid.

A node may contain any number of vertices. A vertex is identified by a name and count pair or by a rank within the node containing it. More than one vertex with the same name can occur within a given node, hence the vertex can be addressed by a name and count pair. Rank is one-based, that is, the first vertex within a node is ranked one. A vertex stores a value of a specific type; supported types are node, integer, 64-bit floating point value, NULL terminated string and uninterpreted binary value of variable length. The e4_Vertex class provides a wide range of methods to manipulate the attributes of a vertex such as its name, type, value and rank. In the following example, a vertex named joe is renamed to barney and then its value is set to an integer value of 42. Next, the vertex's type is changed to 64-bit floating point and its value is changed to 3.14:

e4_Node n;
e4_Vertex v;
...
if (!n.GetVertexRef("joe", v)) {
    cerr << "First vertex named \"joe\" not found.\n";
}
...
if (!v.Rename("barney")) {
    cerr << "Couldn't rename vertex to \"barney\".\n";
}
if (!v.Set(42)) {
    cerr << "Couldn't set vertex value to int value 42.\n";
}
if (!v.Set((double) 3.14)) {
    cerr << "Couldn't set vertex value to double value 3.14.\n";
}
Unfortunately, some C++ compilers require a cast such as (double) to correctly select the method to invoke; in the absence of this cast, they complain that there are multiple methods that could be invoked by the statement.

When setting a vertex value to a NULL terminated string, you can use NULL as the assigned value. If you use NULL, you may have to cast it as (const char *) to disambiguate the method. Similarly, when setting a vertex value to binary uninterpreted data, you can use NULL as the value and also pass zero as the length argument:

e4_Vertex v;
...
if (!v.Set((const char *) NULL)) {
    cerr << "Strange.\n";
}
if (!v.Set((const void *) NULL, 0)) {
    cerr << "Even stranger.\n";
}
The current value of a vertex can be obtained from an e4_Vertex instance for it using the Get method:
e4_Node n;
e4_Vertex v;
int ii;
double dd;
...
if (!n.GetVertexRef("joe", v)) {
    cerr << "First vertex named \"joe\" not found.\n";
}
...
if (!v.Get(ii)) {
    cerr << "Could not retrieve int value of vertex.\n";
}
(void) v.Set((double) 3.14);
if (!v.Get(dd)) {
    cerr << "Strange!\n";
}
The e4_Vertex class provides methods to compute the rank of this field in its containing node, and to obtain e4_Node and e4_Storage instances for the node and storage respectively that contain this field.
  
e4_Vertex Methods and Constructors
   
e4_Vertex() Default constructor. Returns an invalid vertex.
e4_Vertex(const e4_Vertex &ref) Copying constructor. Returns an instance of e4_Vertex whose state is the same as ref.
~e4_Vertex() Destructor. Decrements the reference count for the underlying vertex representation and if this is the last reference, its memory is automatically freed.
e4_Vertex & operator=(const e4_Vertex &ref) Assignment operator. Makes the state of this the same as that of ref and returns this.
bool operator==(const e4_Vertex &comp) const Returns true if comp and this refer to the same vertex or if they are both invalid. Returns false otherwise.
bool operator!=(const e4_Vertex &comp) const Returns true if comp and this refer to different vertices, false if they are the same or if both are invalid.
   
bool Get(e4_Node &n) const Retrieves in n an instance of e4_Node representing the node value of this vertex. Succeeds if the vertex is valid and contains a node value.
bool Get(int &v) const Retrieves in v the integer value of this vertex. Succeeds if the vertex is valid and contains an integer value.
bool Get(double &v) const Retrieves in v the 64-bit floating point value of this vertex. Succeeds if the vertex is valid and contains a 64-bit floating point value.
bool Get(const char *&v) const Retrieves in v the NULL terminated string value of this vertex. Succeeds if the vertex is valid and contains a NULL terminated string value. Note that the memory occupied by the returned value belongs to the e4Graph package and may be reused by the next e4Graph operation.
bool Get(const void *&bytes, int &nbytes) const Retrieves in bytes the binary value of this vertex. Also retrieves the length of the value in nbytes. Succeeds if the vertex is valid and contains a binary uninterpreted value. Note that the memory occupied by the returned value belongs to the e4Graph package and may be reused by the next e4Graph operation.
bool Get(e4_Value &v) const Retrieves in v the value of this vertex. Use this operation if you do not know the type of the value stored in this vertex. If the value is a NULL terminated string or binary value, the memory occupied by the returned value belongs to the e4Graph package and may be reused by the next e4Graph operation.
bool Set(e4_Node n) const Sets the value of this vertex to the node n. As a side effect, the node containing this vertex becomes a parent of n. Succeeds if the vertex and n are valid.
bool Set(int v) const Sets the value of this vertex to the integer value v. Succeeds if the vertex is valid.
bool Set(double v) const Sets the value of this vertex to the 64-bit floating point value v. Succeeds if the vertex is valid.
bool Set(const char *v) const Sets the value of this vertex to the NULL terminated string value v. Succeeds if the vertex is valid.
bool Set(const void *bytes, int nbytes) const Sets the value of this vertex to the binary uninterpreted value bytes of length nbytes. Succeeds if the vertex is valid.
bool Set(e4_Value &val) const Sets the value of this vertex to the value represented by val.
bool SetNode(e4_Node &n) const Sets the value of this vertex to a new instance of e4_Node which is also returned in n. Succeeds if the vertex is valid.
int Rank() const Returns the rank of this vertex within its containing node. If the vertex is not valid, returns E4_VERTEXNOTFOUND.
int CountWithName() const Returns the number of vertices up to and including this one in the node containing this vertex that have the same name as this vertex. If this vertex is detached, returns -1.
int TotalCountWithName() const Returns the total number of vertices in the node containing this one that have the same name as this vertex. If this vertex is detached, returns -1.
int CountWithType() const Returns the number of vertices up to and including this one in the node containing this vertex that have the same type as this vertex. If this vertex is detached, returns -1.
int TotalCountWithType() const Returns the total number of vertices in the node containing this one that have the same type as this vertex. If this vertex is detached, returns -1.
bool Next(int nth, e4_Vertex &v) const Returns the nth vertex after this one in the node containing this vertex. The number nth must be one or larger and equal or less than the difference in rank between the last vertex in this node and this vertex.
bool Prev(int nth, e4_Vertex &v) const Returns the nth vertex before this one in the node containing this vertex. The number nth must be one or larger and less than the rank of this vertex.
bool detach() const Detaches the vertex from the node in which it appears. If the vertex is already detached, does nothing. The vertex count of the node that previously contained this vertex is decremented by one. If the vertex value is a node and after the operation that node is not the value of any attached vertex, the node also becomes detached.
bool IsDetached() const Returns true if this refers to a detached vertex. A vertex is detached if it is not contained within any node. In that case the GetNode operation returns the constant E4_NODENOTFOUND.
bool IsValid() const Returns true if the vertex is valid, false otherwise. A vertex is valid if it is contained within a valid, reachable node.
e4_VertexType Type() const Returns the type of the value stored in this vertex. If the vertex is invalid returns E4_VTUNKNOWN.
const char *Name() const Returns the name of the vertex within its containing node. If the vertex is invalid, returns NULL. Note that the memory occupied by the returned value belongs to the e4Graph package and may be reused by the next e4Graph operation.
bool Rename(const char *newname) const Rename the vertex to newname which cannot be NULL.  Succeeds if the vertex is valid.
bool GetUniqueID(e4_VertexUniqueID &vuid) const Retrieves, in vuid, a type-safe unique identifier for this vertex within this storage. Upon success returns true. If the vertex is invalid returns false.Type-safe unique identifiers are described here
bool GetStorage(e4_Storage &s) const Retrieves in s an instance of e4_Storage that represents the storage containing this vertex.
bool GetNode(e4_Node &n) const Retrieves in n an instance of e4_Node that represents the originating node of this vertex.
bool MoveVertex(e4_Vertex &v, e4_InsertOrder o, int offset) const Inserts the vertex v into the node containing this vertex at a rank relative to the rank of this vertex as indicated by o and offset. If o is E4_IOFIRST or E4_IOLAST, then v is made the first or last vertex in the node, respectively. If o is E4_IOAT, then v is inserted into the node so that its rank is equal to the rank of this vertex; the rank of this vertex is increased by one. If o is E4_IOBEFORE, then v is inserted into the node so that its rank is the rank of this vertex minus offset. If o is E4_IOAFTER, then v is inserted into this node so that its rank is the rank of this vertex plus offset.
bool SetUserData(int userData) const Persistently associates the value of userData with this vertex. The value of this user data is for use by application programs incorporating e4Graph and is not used by e4Graph itself. The default value, unless explicitly set by application programs, is zero.
bool GetUserData(int &userData) const Retrieves, in userData, the user data value associated with this vertex. The default value is zero.
e4_RefKind Kind() const Returns E4_RKVERTEX, the e4_RefKind identifier for the e4_Vertex type.