|
@@ -188,8 +188,9 @@ static int l_graph_add_iter (lua_State *L)
|
|
/// Finalize iterative addition.
|
|
/// Finalize iterative addition.
|
|
static int l_graph_add_done (lua_State *L)
|
|
static int l_graph_add_done (lua_State *L)
|
|
{
|
|
{
|
|
- VOLK_GraphIterator **it_p = lua_touserdata (L, 1);
|
|
|
|
|
|
+ VOLK_GraphIterator **it_p = luaL_checkudata (L, 1, "VOLK.GraphIterator");
|
|
VOLK_graph_add_done (*it_p);
|
|
VOLK_graph_add_done (*it_p);
|
|
|
|
+ *it_p = 0; // it still gets garbage collected, this prevents double-free.
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -324,7 +325,7 @@ static int l_graph_encode (lua_State *L)
|
|
char *tmp = NULL;
|
|
char *tmp = NULL;
|
|
VOLK_rc rc;
|
|
VOLK_rc rc;
|
|
while ((rc = codec.encode_graph_iter (it, &tmp)) != VOLK_END) {
|
|
while ((rc = codec.encode_graph_iter (it, &tmp)) != VOLK_END) {
|
|
- log_debug ("Serialized fragment: %s\n", tmp);
|
|
|
|
|
|
+ //log_debug ("Serialized fragment: %s\n", tmp);
|
|
LUA_PCHECK (rc, "Encoding failed");
|
|
LUA_PCHECK (rc, "Encoding failed");
|
|
out = realloc (out, strlen(out) + strlen (tmp) + 1);
|
|
out = realloc (out, strlen(out) + strlen (tmp) + 1);
|
|
LUA_NLCHECK (out, "Error reallocating serialization buffer.");
|
|
LUA_NLCHECK (out, "Error reallocating serialization buffer.");
|
|
@@ -362,8 +363,14 @@ static int l_graph_get (lua_State *L)
|
|
*
|
|
*
|
|
* @note A new iterator should not be started without first garbage-collecting
|
|
* @note A new iterator should not be started without first garbage-collecting
|
|
* an incomplete one. That would cause a MDB_BAD_RSLOT error on an LMDB-backed
|
|
* an incomplete one. That would cause a MDB_BAD_RSLOT error on an LMDB-backed
|
|
- * graph, because it attempts to open a new read transaction while the old
|
|
|
|
- * iterator is keeping the old one open.
|
|
|
|
|
|
+ * graph, because it attempts to open a new read transaction within the same
|
|
|
|
+ * thread while the old iterator is keeping the old one open. This could be
|
|
|
|
+ * fixed with some good judgment.
|
|
|
|
+ *
|
|
|
|
+ * From the LMDB manual:
|
|
|
|
+ *
|
|
|
|
+ * > A thread can only use one transaction at a time, plus any child
|
|
|
|
+ * > transactions.
|
|
*/
|
|
*/
|
|
static int graph_iter_gc (lua_State *L)
|
|
static int graph_iter_gc (lua_State *L)
|
|
{
|
|
{
|
|
@@ -513,6 +520,7 @@ static const luaL_Reg graph_lib_meth [] = {
|
|
{"copy", l_graph_copy},
|
|
{"copy", l_graph_copy},
|
|
|
|
|
|
{"add", l_graph_add},
|
|
{"add", l_graph_add},
|
|
|
|
+ {"add_init", l_graph_add_init},
|
|
{"remove", l_graph_remove},
|
|
{"remove", l_graph_remove},
|
|
|
|
|
|
{"get_uri", l_graph_get_uri},
|
|
{"get_uri", l_graph_get_uri},
|
|
@@ -532,6 +540,12 @@ static const LEnumConst graph_enums[] = {
|
|
{NULL, 0}
|
|
{NULL, 0}
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+static const luaL_Reg graph_iter_meth [] = {
|
|
|
|
+ {"add_iter", l_graph_add_iter},
|
|
|
|
+ {"add_done", l_graph_add_done},
|
|
|
|
+ {"__gc", graph_iter_gc},
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
|
|
int luaopen_volksdata_graph (lua_State *L)
|
|
int luaopen_volksdata_graph (lua_State *L)
|
|
{
|
|
{
|
|
@@ -541,10 +555,11 @@ int luaopen_volksdata_graph (lua_State *L)
|
|
lua_setfield (L, -2, "__index");
|
|
lua_setfield (L, -2, "__index");
|
|
luaL_setfuncs (L, graph_lib_meth, 0);
|
|
luaL_setfuncs (L, graph_lib_meth, 0);
|
|
|
|
|
|
- // Metatables for ancillary types.
|
|
|
|
|
|
+ // Metatables for graph iterator.
|
|
luaL_newmetatable (L, "VOLK.GraphIterator");
|
|
luaL_newmetatable (L, "VOLK.GraphIterator");
|
|
- lua_pushcfunction (L, graph_iter_gc);
|
|
|
|
- lua_setfield (L, -2, "__gc");
|
|
|
|
|
|
+ lua_pushvalue (L, -1);
|
|
|
|
+ lua_setfield (L, -2, "__index");
|
|
|
|
+ luaL_setfuncs (L, graph_iter_meth, 0);
|
|
|
|
|
|
/*
|
|
/*
|
|
// Getters table.
|
|
// Getters table.
|