Getting Started#
Get Graph from Storage#
GRIN offers a set of APIs to retrieve graph data in storage. The first API we need is to get a graph handle for a graph from storage. The API is:
GRIN_GRAPH grin_get_graph_from_storage(const char* uri);
This API takes a URI as its parameter, which is a string that identifies the graph in storage.
Different storage systems may define different required parameters in the URI:
gart://{etcd_endpoint}?prefix={etcd_prefix}&version={version}
graphar://{yaml_path}?partition_num={partition_num}&strategy={strategy}
v6d://{object_id}?ipc_socket={ipc_socket} where ipc_socket is optional.
The return value of this API is a GRIN graph handle.
Handle#
A handle is an opaque value that identifies an object in GRIN. The type of a handle is
predefined by the storage using typedef
in C
. For example, the handle type
GRIN_GRAPH
we mentioned earlier could be declared as void*
in some storage
implementation.
It is important to note that users should not make any assumptions about the type or value of a handle. Handles should be used as input parameters for related APIs to access the object they represent.
For instance, let’s consider an example where we use the mentioned API to obtain a graph handle. We can then use this handle to check whether the graph is directed. The code is as follows:
1 #include "predefine.h"
2 #include "topology/structure.h"
3
4 int main(int argc, char** argv) {
5 GRIN_GRAPH g = grin_get_graph_from_storage(argv[1]);
6
7 if (grin_is_directed(g)) {
8 printf("The graph is directed");
9 } else {
10 printf("The graph is undirected");
11 }
12 }
In the code snippet, the first line includes the predefine.h
header file, which contains the
necessary typedef for GRIN_GRAPH
and other handles in GRIN. The second line includes the
topology/structure.h
header file, which declares the API bool grin_is_directed(GRIN_GRAPH)
.
Moving on, in the fifth line of the main
function, the graph handle g
is obtained from the
storage using a given uri from the command-line. Finally, in the seventh line, we can check whether
the graph represented by g
is directed.
GRIN provides various handle types, each representing a specific graph concept. These handle types include graph, vertex, edge, vertex list, edge list, adjacent list, and more. We will introduce these handle types in detail when discussing related APIs.
Return Values#
The most common return values of GRIN APIs are handles. These handles correspond to the resources
created by the APIs. To free these resources after use, GRIN provides corresponding destroy
APIs.
For example, when calling the grin_get_graph_from_storage
API, a graph handle is returned, which
can be freed using the grin_destroy_graph
API. It’s important to note that GRIN APIs are stateless,
meaning that the responsibility of memory management lies with the users, rather than the storages.
Some APIs may return values other than handles, such as primitive types like int
and double
.
For example, primitive values returned by APIs to get vertex property values are stored on the stack
,
meaning they do not need to be freed. We will provide more
detailed information about these return values and whether or not there are corresponding
destroy
APIs, when discussing related APIs.
Error Handling#
Each handle type also has a invalid
value.
For example, the GRIN_GRAPH
handle type has a invalid
value denoted as GRIN_NULL_GRAPH
.
When the grin_get_graph_from_storage
API cannot find the graph with the given uri from the storage,
it returns the GRIN_NULL_GRAPH
value. This value can be used to check whether the API call is
successful. An example code snippet is as follows:
#include "predefine.h"
#include "topology/structure.h"
int main(int argc, char** argv) {
GRIN_GRAPH g = grin_get_graph_from_storage(argv[1]);
if (g == GRIN_NULL_GRAPH) {
printf("The graph does not exist");
} else {
printf("The graph exists");
}
}
The GRIN_NULL_GRAPH
value is also defined in the predefine.h
header file,
using a #define
statetment as follows:
#define GRIN_NULL_GRAPH NULL
However, it is hard to define a invalid
value for primitive types like int
or double
.
Therefore, GRIN uses the error code
mechanism to indicate errors for these return value types.
The details can be found in the Error Code
section in Common Functional APIs
.