瀏覽代碼

Introduce borrowed buffers.

scossu 9 月之前
父節點
當前提交
0cae6f611d
共有 5 個文件被更改,包括 62 次插入35 次删除
  1. 53 19
      include/buffer.h
  2. 1 11
      src/buffer.c
  3. 6 4
      src/graph.c
  4. 1 0
      src/store_mdb.c
  5. 1 1
      src/term.c

+ 53 - 19
include/buffer.h

@@ -9,6 +9,27 @@
  */
 #define NULL_KEY 0
 
+
+/// Triple position of s, p, o.
+typedef enum {
+    TRP_POS_S = 0,
+    TRP_POS_P = 1,
+    TRP_POS_O = 2,
+} LSUP_TriplePos;
+
+
+/// Buffer flags, stored in buffer structure.
+typedef enum {
+    LSUP_BUF_BORROWED = 1<<0,       /**< Borrowed buffer. This indicates that
+                                      *  the memory block pointed to by the
+                                      *  buffer is owned by another function,
+                                      *  and instructs #LSUP_buffer_free() to
+                                      *  only free the buffer handle, but not
+                                      *  the underlying data.
+                                      */
+} LSUP_BufferFlag;
+
+
 /** @brief General-purpose data buffer.
  *
  * The structure is transparently exposed so that the related API only defines
@@ -21,6 +42,7 @@
 typedef struct LSUP_Buffer {
     /*@null@*/ unsigned char *addr;
     size_t size;
+    LSUP_BufferFlag flags;
 } LSUP_Buffer;
 
 
@@ -37,12 +59,9 @@ typedef struct buffer_triple_t {
 } LSUP_BufferTriple;
 
 
-typedef enum {
-    TRP_POS_S = 0,
-    TRP_POS_P = 1,
-    TRP_POS_O = 2,
-} LSUP_TriplePos;
-
+/*
+ * Function prototypes.
+ */
 
 /** @brief Initialize or reuse a buffer handle.
  *
@@ -76,7 +95,7 @@ LSUP_buffer_init (
  * @param[in] data Optional data to initially populate the object with. If
  *  NULL, the buffer data are garbage.
  *
- * @return LSUP_Buffer pointer. It must be freed with #LSUP_buffer_free. NULL
+ * @return LSUP_Buffer handle. It must be freed with #LSUP_buffer_free. NULL
  *  on error.
  */
 inline LSUP_Buffer *
@@ -95,6 +114,32 @@ LSUP_buffer_new (const unsigned char *data, const size_t size)
 }
 
 
+/** @brief Create a borrowed buffer (memory view).
+ *
+ * A borrowed buffer does not own the memory block pointed to and should not
+ * be freed. It can be identified by the LSUP_BUF_BORROWED flag.
+ *
+ * @param[in] data Address of data handled by the buffer.
+ *
+ * @param[in] size Length of the data.
+ *
+ * @return LSUP_Buffer handle. It must be freed with #LSUP_buffer_free, which
+ * will correctly leave the underlying data alone. NULL on error.
+ */
+inline LSUP_Buffer *
+LSUP_buffer_new_borrowed (unsigned char *data, const size_t size)
+{
+    LSUP_Buffer *buf;
+    MALLOC_GUARD (buf, NULL);
+
+    buf->addr = data;
+    buf->size = size;
+    buf->flags = LSUP_BUF_BORROWED;
+
+    return buf;
+}
+
+
 /** @brief Dummy buffer to be used with #LSUP_buffer_init.
  */
 #define BUF_DUMMY LSUP_buffer_new (NULL, 0)
@@ -226,17 +271,6 @@ void
 LSUP_btriple_free (LSUP_BufferTriple *sspo);
 
 
-/** @brief Free a buffer triple and its buffer handles but not the buffer data.
- *
- * This is useful when freeing a dummy triple (#LSUP_BTRP_DUMMY) or a triple
- * whose buffers are owned by the caller but the data the terms point to are
- * owned by the store.
- *
- */
-void
-LSUP_btriple_free_shallow (LSUP_BufferTriple *sspo);
-
-
 /** @brief Get serialized triple by term position.
  *
  * Useful for looping over all terms.
@@ -285,7 +319,7 @@ LSUP_btriple_hash (const LSUP_BufferTriple *strp)
  * Triple of dummy buffer, with #LSUP_Buffer size space allocated, but no
  * contents.
  *
- * Free with #LSUP_btriple_free_shallow().
+ * Free with #LSUP_btriple_free().
  */
 #define BTRP_DUMMY LSUP_btriple_new (BUF_DUMMY, BUF_DUMMY, BUF_DUMMY)
 

+ 1 - 11
src/buffer.c

@@ -89,7 +89,7 @@ LSUP_buffer_as_str (const LSUP_Buffer *buf)
 
 void LSUP_buffer_done (LSUP_Buffer *buf)
 {
-    if (LIKELY (buf)) free (buf->addr);
+    if (LIKELY (buf) && !(buf->flags & LSUP_BUF_BORROWED)) free (buf->addr);
 }
 
 void LSUP_buffer_free (LSUP_Buffer *buf)
@@ -154,16 +154,6 @@ LSUP_btriple_free (LSUP_BufferTriple *sspo)
 }
 
 
-void
-LSUP_btriple_free_shallow (LSUP_BufferTriple *sspo)
-{
-    if (UNLIKELY (!sspo)) return;
-
-    sspo->s->addr = sspo->p->addr = sspo->o->addr = NULL;
-    LSUP_btriple_free (sspo);
-}
-
-
 /*
  * Statics.
  */

+ 6 - 4
src/graph.c

@@ -84,7 +84,7 @@ LSUP_graph_get_txn (void *txn, LSUP_Store *store, LSUP_Term *uri, size_t *ct)
     LSUP_graph_add_done (add_it);
     store->sif->lu_free_fn(it);
     LSUP_buffer_free (sc);
-    LSUP_btriple_free_shallow (sspo);
+    LSUP_btriple_free (sspo);
 
     // Do not create a new graph if no results were found.
     if (_ct == 0) {
@@ -168,7 +168,7 @@ LSUP_graph_bool_op_txn (
     gr1->store->sif->lu_free_fn (lu1_it);
 
     res->store->sif->add_done_fn (add_it);
-    LSUP_btriple_free_shallow (sspo);
+    LSUP_btriple_free (sspo);
     LSUP_buffer_free (res_sc);
     LSUP_buffer_free (gr1_sc);
     LSUP_buffer_free (gr2_sc);
@@ -457,8 +457,10 @@ LSUP_graph_lookup_txn (
     if (it->graph->store->sif->features & LSUP_STORE_COW) {
         // Copy-on-wite store.
         it->sspo = BTRP_DUMMY;
-
         if (UNLIKELY (it->sspo == NULL)) return NULL;
+        it->sspo->s->flags |= LSUP_BUF_BORROWED;
+        it->sspo->p->flags |= LSUP_BUF_BORROWED;
+        it->sspo->o->flags |= LSUP_BUF_BORROWED;
     } else {
         // TODO copy-on-retrieval store. No implementations yet.
     }
@@ -501,7 +503,7 @@ LSUP_graph_iter_free (LSUP_GraphIterator *it)
      * the store in case of LSUP_STORE_COW stores.
      */
     if (it->graph->store->sif->features & LSUP_STORE_COW) {
-        LSUP_btriple_free_shallow (it->sspo);
+        LSUP_btriple_free (it->sspo);
         log_debug ("Freeing dummy triple @ %p", it->sspo);
     } else {
         // TODO copy-on-retrieval stores. None yet.

+ 1 - 0
src/store_mdb.c

@@ -726,6 +726,7 @@ key_to_sterm (MDBIterator *it, const LSUP_Key key, LSUP_Buffer *sterm)
 
     db_rc = mdb_get (it->txn, it->store->dbi[IDX_T_ST], &key_v, &data_v);
 
+    sterm->flags |= LSUP_BUF_BORROWED;
     if (db_rc == MDB_SUCCESS) {
         sterm->addr = data_v.mv_data;
         sterm->size = data_v.mv_size;

+ 1 - 1
src/term.c

@@ -344,7 +344,7 @@ LSUP_term_serialize (const LSUP_Term *term)
         memcpy (&metadata, tmp_term->lang, sizeof (metadata));
 
     LSUP_Buffer *sterm;
-    MALLOC_GUARD (sterm, NULL);
+    CALLOC_GUARD (sterm, NULL);
 
     //log_trace ("Effective term being serialized: %s", tmp_term->data);
     int rc = tpl_jot (