Browse Source

Rearrange python module sources.

Stefano Cossu 3 năm trước cách đây
mục cha
commit
e08da1a836
10 tập tin đã thay đổi với 131 bổ sung127 xóa
  1. 50 49
      cpython/py_graph.h
  2. 1 3
      cpython/py_lsup_rdf.c
  3. 9 9
      cpython/py_term.h
  4. 3 2
      cpython/py_triple.h
  5. 0 2
      include/core.h
  6. 7 1
      include/graph.h
  7. 6 3
      include/store_mdb.h
  8. 34 16
      src/graph.c
  9. 16 38
      src/store_mdb.c
  10. 5 4
      src/term.c

+ 50 - 49
cpython/graph_obj.h → cpython/py_graph.h

@@ -7,7 +7,7 @@
 #include <structmember.h>
 
 #include "graph.h"
-#include "triple_obj.h"
+#include "py_triple.h"
 
 
 typedef struct {
@@ -41,65 +41,39 @@ Graph_dealloc (GraphObject *self)
 }
 
 
-static PyObject *
-Graph_get_size (GraphObject *self, void *closure)
-{
-    size_t gr_size = LSUP_graph_size (self->ob_struct);
-    PyObject *size = PyLong_FromSize_t (gr_size);
-
-    Py_INCREF (size);
-    return size;
-}
-
-/*
- * FIXME This should be deleted and the setter set to NULL or omitted, but
- * in doing so Python 3.8 raises a SystemError: bad call flags. See
- * https://bugs.python.org/issue39884 No resolution is clear yet.
- */
-static int
-Graph_set_size (GraphObject *self, PyObject value, void *closure)
-{ return -1; }
-
-
 static PyObject *
 Graph_get_uri (GraphObject *self, void *closure)
 {
     PyObject *uri = PyUnicode_FromString (
             LSUP_graph_uri (self->ob_struct)->data);
 
-    Py_INCREF (uri);
+    Py_INCREF(uri);
     return uri;
 }
 
 
 static int
-Graph_set_uri (GraphObject *self, PyObject *uri, void *closure)
+Graph_set_uri (GraphObject *self, PyObject *value, void *closure)
 {
-    if (PyUnicode_READY (uri) != 0) return -1; // TODO redundant?
-    if (PyUnicode_KIND (uri) != PyUnicode_1BYTE_KIND) return -1;
+    if (PyUnicode_READY(value) != 0) return -1;
+    if (PyUnicode_KIND(value) != PyUnicode_1BYTE_KIND) return -1;
 
-    LSUP_rc rc = LSUP_graph_set_uri (self->ob_struct, PyUnicode_DATA (uri));
+    LSUP_rc rc = LSUP_graph_set_uri (self->ob_struct, PyUnicode_DATA(value));
 
     return rc == LSUP_OK ? 0 : -1;
 }
 
 
 static PyGetSetDef Graph_getsetters[] = {
-    {
-        .name = "__len__",
-        .get = (getter) Graph_get_size,
-        .set = (setter) Graph_set_size,
-        .doc = "Number of triples in the graph.",
-        //.closure = NULL,
-    },
+    /* FIXME This is throwing strange errors.
     {
         "uri", (getter) Graph_get_uri, (setter) Graph_set_uri,
         "Graph URI.", NULL
     },
+    */
     {NULL}
 };
 
-
 static PyObject *
 Graph_copy (PyTypeObject *cls, PyObject *src)
 {
@@ -115,12 +89,13 @@ Graph_copy (PyTypeObject *cls, PyObject *src)
 }
 
 
-/* TODO implement LSUP_graph_equals
 static PyObject *
 Graph_richcmp (PyObject *gr1, PyObject *gr2, int op)
 {
     if (op != Py_EQ && op != Py_NE) Py_RETURN_NOTIMPLEMENTED;
 
+    Py_RETURN_TRUE; // TODO use graph xor == 0
+    /*
     PyObject *res = NULL;
 
     LSUP_Graph *t1 = ((GraphObject *) gr1)->ob_struct;
@@ -128,15 +103,16 @@ Graph_richcmp (PyObject *gr1, PyObject *gr2, int op)
 
     if (LSUP_graph_equals (t1, t2) && op == Py_EQ) Py_RETURN_TRUE;
     Py_RETURN_FALSE;
+    */
  }
-*/
 
 
-/* TODO Implement mdbstore bool ops
 static inline PyObject *
 Graph_bool_op (
         PyTypeObject *cls, LSUP_bool_op op, PyObject *gr1, PyObject *gr2)
 {
+    Py_RETURN_NONE; //TODO Implement mdbstore bool ops
+    /*
     if (! PyObject_TypeCheck (gr1, cls) || ! PyObject_TypeCheck (gr2, cls))
         return NULL;
 
@@ -149,14 +125,20 @@ Graph_bool_op (
 
     Py_INCREF(res);
     return (PyObject *) res;
+    */
 }
-*/
 
 
-static int Graph_add (PyObject *self, PyObject *triples)
+static PyObject *
+Graph_add (PyObject *self, PyObject *triples)
 {
     // Triple may be any iterable.
-    if (! PyIter_Check (triples)) return -1;
+    PyObject *iter = PyObject_GetIter (triples);
+    if (! iter) {
+        PyErr_SetString (
+                PyExc_ValueError, "Triples object cannot be iterated.");
+        return NULL;
+    }
 
     PyObject *trp_obj = NULL;
     int rc = 0;
@@ -165,8 +147,10 @@ static int Graph_add (PyObject *self, PyObject *triples)
     LSUP_GraphIterator *it = LSUP_graph_add_stream_init (
             ((GraphObject *)self)->ob_struct);
 
-    for (i = 0; (trp_obj = PyIter_Next (triples)); i++) {
+    for (i = 0; (trp_obj = PyIter_Next (iter)); i++) {
         if (!PyObject_TypeCheck (trp_obj, &TripleType)) {
+            PyErr_SetString (
+                    PyExc_ValueError, "Object is not a triple.");
             rc = -1;
             goto finalize;
         }
@@ -182,13 +166,18 @@ static int Graph_add (PyObject *self, PyObject *triples)
             goto finalize;
         }
     }
-    LSUP_striple_free (sspo);
 
 finalize:
     LSUP_graph_add_stream_done (it);
     LSUP_striple_free (sspo);
 
-    return rc;
+    PyObject *ret = PyLong_FromSize_t (LSUP_graph_iter_cur (it));
+
+    if (rc == 0) {
+        Py_INCREF (ret);
+        return ret;
+    }
+    return NULL;
 }
 
 
@@ -205,6 +194,7 @@ static PyObject *Graph_lookup (
 
 
 static PyMethodDef Graph_methods[] = {
+    {"uri", (PyCFunction) Graph_get_uri, METH_NOARGS, "Get the graph URI."},
     {"copy", (PyCFunction) Graph_copy, METH_CLASS, "Copy a graph."},
     {"add", (PyCFunction) Graph_add, METH_O, "Add triples to a graph."},
     {
@@ -218,7 +208,6 @@ static PyMethodDef Graph_methods[] = {
 };
 
 
-/* TODO Implement mdbstore bool ops
 static inline PyObject *Graph_bool_and (
         PyTypeObject *cls, PyObject *gr1, PyObject *gr2)
 { return Graph_bool_op (cls, LSUP_BOOL_INTERSECTION, gr1, gr2); }
@@ -241,22 +230,34 @@ static PyNumberMethods Graph_number_methods = {
     .nb_subtract = (binaryfunc) Graph_bool_subtract,
     .nb_xor = (binaryfunc) Graph_bool_xor,
 };
-*/
+
+
+static Py_ssize_t
+Graph_get_size (PyObject *self)
+{ return LSUP_graph_size (((GraphObject *) self)->ob_struct); }
+
+
+static PySequenceMethods Graph_seq_methods = {
+    .sq_length = (lenfunc) Graph_get_size,
+    //.sq_contains = Graph_contains, // TODO
+};
+
 
 PyTypeObject GraphType = {
     PyVarObject_HEAD_INIT(NULL, 0)
     .tp_name = "graph.Graph",
     .tp_doc = "RDF graph",
-    .tp_basicsize = sizeof(GraphObject),
+    .tp_basicsize = sizeof (GraphObject),
     .tp_itemsize = 0,
     .tp_flags = Py_TPFLAGS_DEFAULT,
     .tp_new = PyType_GenericNew,
     .tp_init = (initproc) Graph_init,
     .tp_dealloc = (destructor) Graph_dealloc,
-    .tp_methods = Graph_methods,
     .tp_getset = Graph_getsetters,
-    //.tp_richcompare = Graph_richcmp, TODO implement LSUP_graph_equals
-    //.tp_as_number = &Graph_number_methods,
+    .tp_methods = Graph_methods,
+    .tp_richcompare = Graph_richcmp,
+    .tp_as_number = &Graph_number_methods,
+    .tp_as_sequence = &Graph_seq_methods,
 };
 
 #endif

+ 1 - 3
cpython/lsup_rdf_mod.c → cpython/py_lsup_rdf.c

@@ -11,9 +11,7 @@
 
 #include <Python.h>
 
-#include "term_obj.h"
-#include "triple_obj.h"
-#include "graph_obj.h"
+#include "py_graph.h"
 
 
 static PyModuleDef lsup_rdf_pkg = {

+ 9 - 9
cpython/term_obj.h → cpython/py_term.h

@@ -46,38 +46,38 @@ Term_dealloc (TermObject *self)
 
 
 static PyObject *
-Term_get_type (TermObject *self)
+Term_get_type (TermObject *self, void *closure)
 {
     PyObject *type = PyLong_FromLong (self->ob_struct->type);
-    Py_INCREF (type);
 
+    Py_INCREF (type);
     return type;
 }
 
 
 static PyObject *
-Term_get_data (TermObject *self)
+Term_get_data (TermObject *self, void *closure)
 {
     PyObject *data = PyUnicode_FromString (self->ob_struct->data);
-    Py_INCREF (data);
 
+    Py_INCREF (data);
     return data;
 }
 
 
 static PyObject *
-Term_get_datatype (TermObject *self)
+Term_get_datatype (TermObject *self, void *closure)
 {
     if (!self->ob_struct->datatype) Py_RETURN_NONE;
 
     PyObject *datatype = PyUnicode_FromString (self->ob_struct->datatype);
-    Py_INCREF (datatype);
 
+    Py_INCREF (datatype);
     return datatype;
 }
 
 static PyObject *
-Term_get_lang (TermObject *self)
+Term_get_lang (TermObject *self, void *closure)
 {
     if (
             !self->ob_struct->datatype || !self->ob_struct->lang ||
@@ -85,8 +85,8 @@ Term_get_lang (TermObject *self)
         Py_RETURN_NONE;
 
     PyObject *lang = PyUnicode_FromString (self->ob_struct->lang);
-    Py_INCREF (lang);
 
+    Py_INCREF (lang);
     return lang;
 }
 
@@ -114,7 +114,7 @@ PyTypeObject TermType = {
     PyVarObject_HEAD_INIT(NULL, 0)
     .tp_name = "term.Term",
     .tp_doc = "RDF term",
-    .tp_basicsize = sizeof(TermObject),
+    .tp_basicsize = sizeof (TermObject),
     .tp_itemsize = 0,
     .tp_flags = Py_TPFLAGS_DEFAULT,
     .tp_new = PyType_GenericNew,

+ 3 - 2
cpython/triple_obj.h → cpython/py_triple.h

@@ -7,7 +7,7 @@
 #include <structmember.h>
 
 #include "triple.h"
-#include "term_obj.h"
+#include "py_term.h"
 
 
 typedef struct {
@@ -22,7 +22,8 @@ typedef struct {
 static int
 Triple_init (TripleObject *self, PyObject *args)
 {
-    PyObject *s = NULL, *p = NULL, *o = NULL, *tmp;
+    PyObject *s = NULL, *p = NULL, *o = NULL;
+    TermObject *tmp;
 
     if (! PyArg_ParseTuple (
                 args, "O!O!O!", &TermType, &s,

+ 0 - 2
include/core.h

@@ -29,8 +29,6 @@
 
 #define LIKELY(x)       __builtin_expect(!!(x), true)
 #define UNLIKELY(x)     __builtin_expect(!!(x), false)
-// TODO Handle memory errors better.
-#define CRITICAL(exp)   if (UNLIKELY ((exp) == NULL)) abort()
 
 // TODO Cross-platform ramdisk path.
 #define TMPDIR "/tmp"

+ 7 - 1
include/graph.h

@@ -197,7 +197,7 @@ LSUP_graph_remove (LSUP_Graph *gr, const LSUP_Triple *spo, size_t *ct);
  *  freed with #LSUP_graph_iter_free after use.
  */
 LSUP_GraphIterator *
-LSUP_graph_lookup (const LSUP_Graph *gr, const LSUP_Triple *spo);
+LSUP_graph_lookup (const LSUP_Graph *gr, const LSUP_Triple *spo, size_t *ct);
 
 
 /** @brief Advance a cursor obtained by a lookup and return a matching triple.
@@ -219,4 +219,10 @@ LSUP_graph_iter_next (LSUP_GraphIterator *it, LSUP_Triple *spo);
 void
 LSUP_graph_iter_free (LSUP_GraphIterator *it);
 
+
+/** @brief Get the iterator counter.
+ */
+size_t
+LSUP_graph_iter_cur (LSUP_GraphIterator *it);
+
 #endif

+ 6 - 3
include/store_mdb.h

@@ -25,6 +25,9 @@
 #include "lmdb.h"
 #include "triple.h"
 
+// FIXME find a better cross-platform path.
+#define DEFAULT_ENV_PATH "./mdb_store"
+
 typedef char DbLabel[8];
 typedef struct MDBStore LSUP_MDBStore;
 typedef struct MDBIterator LSUP_MDBIterator;
@@ -50,7 +53,7 @@ typedef LSUP_rc (*store_match_fn_t)(const LSUP_TripleKey spok, void *data);
  *  in which case it will be set either to the environment variable
  *  LSUP_STORE_PATH, or if that is not set, a default local path.
  */
-LSUP_rc LSUP_mdbstore_setup (char **path, bool clear);
+LSUP_rc LSUP_mdbstore_setup (char *path, bool clear);
 
 
 /** @brief Open an MDB store.
@@ -147,7 +150,7 @@ LSUP_mdbstore_add_iter (struct MDBIterator *it, const LSUP_SerTriple *sspo);
 
 /** @brief Finalize an add loop and free iterator.
  *
- * If a count of inserted records is needed, #LSUP_mdbiter_i must be called
+ * If a count of inserted records is needed, #LSUP_mdbiter_cur must be called
  * before this function.
  *
  * This must be called after #LSUP_mdbstore_add_iter.
@@ -271,7 +274,7 @@ LSUP_rc LSUP_mdbiter_next (LSUP_MDBIterator *it, LSUP_SerTriple *sspo);
  *  of succcessfully inserted records.
  */
 size_t
-LSUP_mdbiter_i (LSUP_MDBIterator *it);
+LSUP_mdbiter_cur (LSUP_MDBIterator *it);
 
 
 /** @brief Free an iterator allocated by a lookup.

+ 34 - 16
src/graph.c

@@ -45,7 +45,6 @@ typedef struct GraphIterator {
         LSUP_MDBIterator *  mdb_iter;
     };
     size_t                  ct;         // Total matches.
-    size_t                  i;          // Cursor.
 } GraphIterator;
 
 
@@ -101,8 +100,9 @@ LSUP_graph_new (const LSUP_store_type store_type)
 {
     if (!check_backend (store_type)) return NULL;
 
-    LSUP_Graph *gr;
-    CRITICAL (gr = malloc (sizeof (LSUP_Graph)));
+    LSUP_Graph *gr = malloc (sizeof (LSUP_Graph));
+    if (UNLIKELY (!gr)) return NULL;
+
     gr->uri = LSUP_uri_new (NULL);
     gr->store_type = store_type;
 
@@ -138,12 +138,12 @@ graph_copy_contents (const LSUP_Graph *src, LSUP_Graph *dest)
     LSUP_rc rc = LSUP_NOACTION;
     const LSUP_Triple trp = {NULL, NULL, NULL};
 
-    GraphIterator *it = LSUP_graph_lookup (src, &trp);
+    GraphIterator *it = LSUP_graph_lookup (src, &trp, NULL);
 
     LSUP_SerTriple sspo;
 
     while (graph_iter_next_buffer (it, &sspo) != LSUP_END) {
-        TRACE ("Inserting triple #%lu\n", it->i);
+        TRACE ("Inserting triple #%lu\n", LSUP_graph_iter_cur (it));
         LSUP_rc add_rc = LSUP_graph_add (dest, NULL, 0, &sspo, 1, NULL);
         if (LIKELY (add_rc == LSUP_OK)) rc = LSUP_OK;
         else if (add_rc < 0) return add_rc;
@@ -252,19 +252,21 @@ LSUP_graph_size (const Graph *gr)
     return LSUP_mdbstore_size (gr->mdb_store);
 }
 
+// TODO Add add_stream_init, add_stream_iter and add_stream_done for streaming
+// functions.
 
 GraphIterator *
 LSUP_graph_add_stream_init (LSUP_Graph *gr)
 {
     GraphIterator *it = malloc (sizeof (*it));
-    if (!it) return NULL;
+    if (UNLIKELY (!it)) return NULL;
 
     LSUP_Buffer *sc = LSUP_buffer_new_from_term (gr->uri);
     it->mdb_iter = LSUP_mdbstore_add_init (gr->mdb_store, sc);
     LSUP_buffer_free (sc);
 
     it->graph = gr;
-    it->i = 0;
+    //it->i = 0;
 
     return it;
 }
@@ -404,10 +406,10 @@ LSUP_graph_remove (Graph *gr, const LSUP_Triple *spo, size_t *ct)
 
 
 GraphIterator *
-LSUP_graph_lookup (const Graph *gr, const LSUP_Triple *spo)
+LSUP_graph_lookup (const Graph *gr, const LSUP_Triple *spo, size_t *ct)
 {
-    GraphIterator *it;
-    CRITICAL (it = malloc (sizeof (GraphIterator)));
+    GraphIterator *it = malloc (sizeof (GraphIterator));
+    if (UNLIKELY (!it)) return NULL;
 
     it->graph = gr;
 
@@ -418,7 +420,7 @@ LSUP_graph_lookup (const Graph *gr, const LSUP_Triple *spo)
         // TODO uncomment it->ht_iter = LSUP_htstore_lookup (gr->ht_store, sspo, &it->ct);
 
     } else {
-        it->mdb_iter = LSUP_mdbstore_lookup (gr->mdb_store, sspo, sc, &it->ct);
+        it->mdb_iter = LSUP_mdbstore_lookup (gr->mdb_store, sspo, sc, ct);
     }
 
     LSUP_striple_free (sspo);
@@ -460,8 +462,6 @@ LSUP_graph_iter_next (GraphIterator *it, LSUP_Triple *spo)
             LSUP_term_deserialize (sspo->p, spo->p);
             LSUP_term_deserialize (sspo->o, spo->o);
         }
-
-        it->i++;
     }
 
     // Addresses of triple buffers are owned by the DB. Do not free.
@@ -488,10 +488,15 @@ LSUP_graph_iter_free (GraphIterator *it)
 }
 
 
+size_t
+LSUP_graph_iter_cur (GraphIterator *it)
+{ return LSUP_mdbiter_cur (it->mdb_iter); }
+
+
 bool
 LSUP_graph_contains (const LSUP_Graph *gr, const LSUP_Triple *spo)
 {
-    GraphIterator *it = LSUP_graph_lookup (gr, spo);
+    GraphIterator *it = LSUP_graph_lookup (gr, spo, NULL);
     bool rc = LSUP_graph_iter_next (it, NULL) != LSUP_NORESULT;
 
     LSUP_graph_iter_free (it);
@@ -514,12 +519,25 @@ mdbstore_init()
 {
     if (UNLIKELY (!default_ctx)) {
         // RAM disk store.
+        printf("Initilalizing RAM disk back end.\n");
         char *path = MDB_RAMDISK_PATH;
-        if (LSUP_mdbstore_setup (&path, true) != LSUP_OK) return LSUP_DB_ERR;
+        if (LSUP_mdbstore_setup (path, true) != LSUP_OK) return LSUP_DB_ERR;
 
         // Permanent store.
+        printf("Initilalizing persistent back end.\n");
+        // NOTE This method will only allow one persistent disk back end per
+        // application. TODO maybe later allow multiple backends if useful.
         path = getenv ("LSUP_MDB_STORE_PATH");
-        if (LSUP_mdbstore_setup (&path, false) != LSUP_OK) return LSUP_DB_ERR;
+        if (!path) {
+            path = DEFAULT_ENV_PATH;
+            fprintf(
+                stderr,
+                "WARNING: `LSUP_STORE_PATH' environment variable is not set. "
+                "The default location %s will be used as the graph store.\n",
+                path
+            );
+        }
+        if (LSUP_mdbstore_setup (path, false) != LSUP_OK) return LSUP_DB_ERR;
 
         LSUP_Term *default_ctx_uri = LSUP_uri_new (default_ctx_label);
         default_ctx = LSUP_buffer_new_from_term (default_ctx_uri);

+ 16 - 38
src/store_mdb.c

@@ -17,7 +17,6 @@
     #define DEFAULT_MAPSIZE 1UL<<40 // 1Tb
 #endif
 
-#define DEFAULT_ENV_PATH "./mdb_store"
 #define ENV_DIR_MODE 0750
 #define ENV_FILE_MODE 0640
 
@@ -168,19 +167,6 @@ static DBIdx lookup_indices[9] = {
 #undef ENTRY
 };
 
-/**
- * Order in which keys are looked up if two terms are bound.
- * The indices with the smallest average number of values per key should be
- * looked up first.
- *
- * TODO deprecate?
- *
- * 0 = s:po
- * 1 = p:so
- * 2 = o:sp
- */
-// static const uint8_t lookup_rank[3] = {0, 2, 1};
-
 static const uint8_t lookup_ordering_1bound[3][3] = {
     {0, 1, 2}, // s:po
     {1, 0, 2}, // p:so
@@ -215,34 +201,25 @@ inline static LSUP_rc lookup_3bound(
  */
 
 LSUP_rc
-LSUP_mdbstore_setup (char **path, bool clear)
+LSUP_mdbstore_setup (char *path, bool clear)
 {
     int rc;
 
     // Set environment path.
-    if (path == NULL && (*path = getenv ("LSUP_STORE_PATH")) == NULL) {
-        // FIXME This won't work for multiple graphs with different disk
-        // back ends. A random path generator needs to be used.
-        *path = DEFAULT_ENV_PATH;
-        fprintf(
-                stderr,
-                "WARNING: `LSUP_STORE_PATH' environment variable is not set. "
-                "The default location %s will be used as the graph store.\n",
-                *path);
-    }
+    if (!path) return LSUP_ERROR;
 
     // TODO Verify that a writable directory exists or can be created.
     //struct stat path_stat;
 
-    if (clear) rm_r (*path);
-    if (mkdir_p (*path, ENV_DIR_MODE) != 0) return LSUP_IO_ERR;
+    if (clear) rm_r (path);
+    if (mkdir_p (path, ENV_DIR_MODE) != 0) return LSUP_IO_ERR;
 
     // Open a temporary environment and txn to create the DBs.
     MDB_env *env;
     mdb_env_create (&env);
 
     mdb_env_set_maxdbs (env, N_DB);
-    mdb_env_open (env, *path, 0, ENV_FILE_MODE);
+    mdb_env_open (env, path, 0, ENV_FILE_MODE);
 
     MDB_txn *txn;
     mdb_txn_begin (env, NULL, 0, &txn);
@@ -264,8 +241,8 @@ MDBStore *
 LSUP_mdbstore_new (const char *path, const LSUP_Buffer *default_ctx)
 {
     int db_rc;
-    LSUP_MDBStore *store;
-    CRITICAL (store = malloc (sizeof (LSUP_MDBStore)));
+    LSUP_MDBStore *store = malloc (sizeof (LSUP_MDBStore));
+    if (UNLIKELY (!store)) return NULL;
 
     db_rc = mdb_env_create (&store->env);
     TRACE ("create rc: %d", db_rc);
@@ -360,7 +337,7 @@ LSUP_mdbstore_add_init (LSUP_MDBStore *store, const LSUP_Buffer *sc)
      * its job without having to define a very similar struct.
      */
     MDBIterator *it = malloc (sizeof (*it));
-    if (!it) return NULL;
+    if (UNLIKELY (!it)) return NULL;
 
     it->store = store;
     it->i = 0;
@@ -566,8 +543,8 @@ LSUP_mdbstore_lookup(
         LSUP_sterm_to_key (sspo->o),
     };
 
-    LSUP_MDBIterator *it;
-    CRITICAL (it = malloc (sizeof (*it)));
+    LSUP_MDBIterator *it = malloc (sizeof (*it));
+    if (UNLIKELY (!it)) return NULL;
 
     it->store = store;
     it->ck = store->default_ctx ? LSUP_sterm_to_key (sc) : NULL_KEY;
@@ -643,6 +620,7 @@ mdbiter_next_key (LSUP_MDBIterator *it)
 
     LSUP_rc rc;
 
+    it->i++;
     it->iter_op_fn (it);
 
     if (it->ck) {
@@ -712,7 +690,7 @@ LSUP_mdbiter_next (LSUP_MDBIterator *it, LSUP_SerTriple *sspo)
 
 
 size_t
-LSUP_mdbiter_i (LSUP_MDBIterator *it)
+LSUP_mdbiter_cur (LSUP_MDBIterator *it)
 { return it->i; }
 
 
@@ -1092,8 +1070,8 @@ lookup_1bound (MDBStore *store, uint8_t idx0, MDBIterator *it, size_t *ct)
         // If a context is specified, the only way to count triples matching
         // the context is to loop over them.
         if (it->ck != NULL_KEY) {
-            MDBIterator *ct_it;
-            CRITICAL (ct_it = malloc (sizeof (MDBIterator)));
+            MDBIterator *ct_it = malloc (sizeof (MDBIterator));
+            if (UNLIKELY (!ct_it)) return LSUP_MEM_ERR;
 
             ct_it->luk[0] = it->luk[0];
             /*
@@ -1204,8 +1182,8 @@ lookup_2bound(
         // If a context is specified, the only way to count triples matching
         // the context is to loop over them.
         if (it->ck != NULL_KEY) {
-            MDBIterator *ct_it;
-            CRITICAL (ct_it = malloc (sizeof (MDBIterator)));
+            MDBIterator *ct_it = malloc (sizeof (MDBIterator));
+            if (UNLIKELY (!ct_it)) return LSUP_MEM_ERR;
 
             ct_it->luk[0] = it->luk[0];
             ct_it->luk[1] = it->luk[1];

+ 5 - 4
src/term.c

@@ -42,8 +42,9 @@ LSUP_term_new (
 LSUP_Term *
 LSUP_term_new_from_buffer (const LSUP_Buffer *sterm)
 {
-    LSUP_Term *term;
-    CRITICAL (term = malloc (sizeof (*term)));
+    LSUP_Term *term = malloc (sizeof (*term));
+    if (UNLIKELY (!term)) return NULL;
+
     if (UNLIKELY (LSUP_term_deserialize (sterm, term) != LSUP_OK)) {
         free (term);
         return NULL;
@@ -56,8 +57,8 @@ LSUP_term_new_from_buffer (const LSUP_Buffer *sterm)
 LSUP_Buffer *
 LSUP_buffer_new_from_term (const LSUP_Term *term)
 {
-    LSUP_Buffer *sterm;
-    CRITICAL (sterm = malloc (sizeof (*sterm)));
+    LSUP_Buffer *sterm = malloc (sizeof (*sterm));
+    if (UNLIKELY (!sterm)) return NULL;
     sterm->addr = NULL;
 
     if (LSUP_term_serialize (term, sterm) != LSUP_OK) {