[PATCH 1/2] NVTable: allow huge LogMessage data

Balazs Scheidler bazsi at balabit.hu
Tue Jan 31 18:14:44 CET 2012


This patch converts NVTable to use 32 bit offsets/sizes in order to allow
maximum 4GB log records, each value holding maximum 4GB data. The NVTable
structure is still artificially limited to 256MB in size.

Signed-off-by: Peter Eisenlohr <peter.eisenlohr at inform-software.com>
Signed-off-by: Balazs Scheidler <bazsi at balabit.hu>
---
 lib/logmsg.h              |    9 +++-
 lib/nvtable.c             |  114 +++++++++++++++++++++++---------------------
 lib/nvtable.h             |   68 ++++++++++++++-------------
 tests/unit/test_nvtable.c |    8 ++--
 4 files changed, 107 insertions(+), 92 deletions(-)

diff --git a/lib/logmsg.h b/lib/logmsg.h
index 418b884..926a50c 100644
--- a/lib/logmsg.h
+++ b/lib/logmsg.h
@@ -62,6 +62,13 @@ enum
   LM_V_MSGID,
   LM_V_SOURCE,
   LM_V_LEGACY_MSGHDR,
+
+  /* NOTE: this is used as the number of "statically" allocated elements in
+   * an NVTable.  NVTable may impose restrictions on this value (for
+   * instance had to be an even number earlier).  So be sure to validate
+   * whether LM_V_MAX would fit NVTable if you add further enums here.
+   */
+
   LM_V_MAX,
 };
 
@@ -203,7 +210,7 @@ log_msg_get_value(LogMessage *self, NVHandle handle, gssize *value_len)
 
   flags = nv_registry_get_handle_flags(logmsg_registry, handle);
   if ((flags & LM_VF_MACRO) == 0)
-    return __nv_table_get_value(self->payload, handle, NV_TABLE_BOUND_NUM_STATIC(LM_V_MAX), value_len);
+    return __nv_table_get_value(self->payload, handle, LM_V_MAX, value_len);
   else
     return log_msg_get_macro_value(self, flags >> 8, value_len);
 }
diff --git a/lib/nvtable.c b/lib/nvtable.c
index adf4693..e86b6c3 100644
--- a/lib/nvtable.c
+++ b/lib/nvtable.c
@@ -147,34 +147,35 @@ nv_registry_free(NVRegistry *self)
 
 /* clonable LogMessage support with shared data pointers */
 
-#define NV_TABLE_DYNVALUE_HANDLE(x)  ((x) >> 16)
-#define NV_TABLE_DYNVALUE_OFS(x)  ((x) & 0xFFFF)
+#define NV_TABLE_DYNVALUE_HANDLE(x) ((x).handle)
+#define NV_TABLE_DYNVALUE_OFS(x)    ((x).ofs)
 
 
 static inline gchar *
 nv_table_get_bottom(NVTable *self)
 {
-  return nv_table_get_top(self) - (self->used << NV_TABLE_SCALE);
+  return nv_table_get_top(self) - self->used;
 }
 
 static inline gchar *
 nv_table_get_ofs_table_top(NVTable *self)
 {
-  return (gchar *) &self->data[self->num_static_entries * sizeof(self->static_entries[0]) + self->num_dyn_entries * sizeof(guint32)];
+  return (gchar *) &self->data[self->num_static_entries * sizeof(self->static_entries[0]) +
+                               self->num_dyn_entries * sizeof(NVDynValue)];
 }
 
 static inline NVEntry *
-nv_table_get_entry_at_ofs(NVTable *self, guint16 ofs)
+nv_table_get_entry_at_ofs(NVTable *self, guint32 ofs)
 {
   if (!ofs)
     return NULL;
-  return (NVEntry *) (nv_table_get_top(self) - (ofs << NV_TABLE_SCALE));
+  return (NVEntry *) (nv_table_get_top(self) - ofs);
 }
 
-static inline guint32 *
+static inline NVDynValue *
 nv_table_get_dyn_entries(NVTable *self)
 {
-  return (guint32 *) &self->static_entries[self->num_static_entries];
+  return (NVDynValue *) &self->static_entries[self->num_static_entries];
 }
 
 static inline gboolean
@@ -195,9 +196,9 @@ nv_table_alloc_value(NVTable *self, gsize alloc_size)
   /* alloc error, NVTable should be realloced */
   if (!nv_table_alloc_check(self, alloc_size))
     return NULL;
-  self->used += alloc_size >> NV_TABLE_SCALE;
-  entry = (NVEntry *) (nv_table_get_top(self) - (self->used << NV_TABLE_SCALE));
-  entry->alloc_len = alloc_size >> NV_TABLE_SCALE;
+  self->used += alloc_size;
+  entry = (NVEntry *) (nv_table_get_top(self) - (self->used));
+  entry->alloc_len = alloc_size;
   entry->indirect = FALSE;
   entry->referenced = FALSE;
   return entry;
@@ -211,8 +212,11 @@ nv_table_resolve_indirect(NVTable *self, NVEntry *entry, gssize *length)
   gssize referenced_length;
 
   referenced_value = nv_table_get_value(self, entry->vindirect.handle, &referenced_length);
-  if (entry->vindirect.ofs > referenced_length)
+  if (entry->vindirect.ofs > referenced_length) {
+    if (length)
+      *length = 0;
     return null_string;
+  }
 
   /* here we assume that indirect references are only looked up with
    * non-zero terminated strings properly handled, thus the caller has
@@ -228,7 +232,7 @@ nv_table_resolve_entry(NVTable *self, NVEntry *entry, gssize *length)
   if (!entry->indirect)
     {
       if (length)
-        *length = entry->vdirect.value_len_lo + (entry->vdirect.value_len_hi << 16);
+        *length = entry->vdirect.value_len;
       return entry->vdirect.data + entry->name_len + 1;
     }
   else
@@ -236,11 +240,11 @@ nv_table_resolve_entry(NVTable *self, NVEntry *entry, gssize *length)
 }
 
 NVEntry *
-nv_table_get_entry_slow(NVTable *self, NVHandle handle, guint32 **dyn_slot)
+nv_table_get_entry_slow(NVTable *self, NVHandle handle, NVDynValue **dyn_slot)
 {
-  guint16 ofs;
+  guint32 ofs;
   gint l, h, m;
-  guint32 *dyn_entries = nv_table_get_dyn_entries(self);
+  NVDynValue *dyn_entries = nv_table_get_dyn_entries(self);
   guint32 mv;
 
   if (!self->num_dyn_entries)
@@ -274,16 +278,17 @@ nv_table_get_entry_slow(NVTable *self, NVHandle handle, guint32 **dyn_slot)
         }
     }
 
-  return nv_table_get_entry_at_ofs(self, ofs);
+  NVEntry *entry = nv_table_get_entry_at_ofs(self, ofs);
+  return entry;
 }
 
 static gboolean
-nv_table_reserve_table_entry(NVTable *self, NVHandle handle, guint32 **dyn_slot)
+nv_table_reserve_table_entry(NVTable *self, NVHandle handle, NVDynValue **dyn_slot)
 {
   if (G_UNLIKELY(!(*dyn_slot) && handle > self->num_static_entries))
     {
       /* this is a dynamic value */
-      guint32 *dyn_entries = nv_table_get_dyn_entries(self);;
+      NVDynValue *dyn_entries = nv_table_get_dyn_entries(self);;
       gint l, h, m, ndx;
       gboolean found = FALSE;
 
@@ -329,7 +334,8 @@ nv_table_reserve_table_entry(NVTable *self, NVHandle handle, guint32 **dyn_slot)
 
       /* we set ofs to zero here, which means that the NVEntry won't
          be found even if the slot is present in dyn_entries */
-      **dyn_slot = (handle << 16) + 0;
+      (**dyn_slot).handle = handle;
+      (**dyn_slot).ofs    = 0;
       if (!found)
         self->num_dyn_entries++;
     }
@@ -337,7 +343,7 @@ nv_table_reserve_table_entry(NVTable *self, NVHandle handle, guint32 **dyn_slot)
 }
 
 static inline void
-nv_table_set_table_entry(NVTable *self, NVHandle handle, guint16 ofs, guint32 *dyn_slot)
+nv_table_set_table_entry(NVTable *self, NVHandle handle, guint32 ofs, NVDynValue *dyn_slot)
 {
   if (G_LIKELY(handle <= self->num_static_entries))
     {
@@ -347,7 +353,8 @@ nv_table_set_table_entry(NVTable *self, NVHandle handle, guint16 ofs, guint32 *d
   else
     {
       /* this is a dynamic value */
-      *dyn_slot = (handle << 16) + ofs;
+      (*dyn_slot).handle = handle;
+      (*dyn_slot).ofs    = ofs;
     }
 }
 
@@ -379,11 +386,11 @@ gboolean
 nv_table_add_value(NVTable *self, NVHandle handle, const gchar *name, gsize name_len, const gchar *value, gsize value_len, gboolean *new_entry)
 {
   NVEntry *entry;
-  guint16 ofs;
-  guint32 *dyn_slot;
+  guint32 ofs;
+  NVDynValue *dyn_slot;
 
-  if (value_len > 255 * 1024)
-    value_len = 255 * 1024;
+  if (value_len > NV_TABLE_MAX_BYTES)
+    value_len = NV_TABLE_MAX_BYTES;
   if (new_entry)
     *new_entry = FALSE;
   entry = nv_table_get_entry(self, handle, &dyn_slot);
@@ -407,7 +414,7 @@ nv_table_add_value(NVTable *self, NVHandle handle, const gchar *name, gsize name
           return FALSE;
         }
     }
-  if (G_UNLIKELY(entry && (((guint) entry->alloc_len << NV_TABLE_SCALE)) >= value_len + NV_ENTRY_DIRECT_HDR + name_len + 2))
+  if (G_UNLIKELY(entry && (((guint) entry->alloc_len)) >= value_len + NV_ENTRY_DIRECT_HDR + name_len + 2))
     {
       gchar *dst;
       /* this value already exists and the new value fits in the old space */
@@ -415,8 +422,7 @@ nv_table_add_value(NVTable *self, NVHandle handle, const gchar *name, gsize name
         {
           dst = entry->vdirect.data + entry->name_len + 1;
 
-          entry->vdirect.value_len_lo = value_len & 0xFFFF;
-          entry->vdirect.value_len_hi = (value_len >> 16);
+          entry->vdirect.value_len = value_len;
           memcpy(dst, value, value_len);
           dst[value_len] = 0;
         }
@@ -424,8 +430,7 @@ nv_table_add_value(NVTable *self, NVHandle handle, const gchar *name, gsize name
         {
           /* this was an indirect entry, convert it */
           entry->indirect = 0;
-          entry->vdirect.value_len_lo = value_len & 0xFFFF;
-          entry->vdirect.value_len_hi = (value_len >> 16);
+          entry->vdirect.value_len = value_len;
           entry->name_len = name_len;
           memcpy(entry->vdirect.data, name, name_len + 1);
           memcpy(entry->vdirect.data + name_len + 1, value, value_len);
@@ -446,9 +451,8 @@ nv_table_add_value(NVTable *self, NVHandle handle, const gchar *name, gsize name
       return FALSE;
     }
 
-  ofs = (nv_table_get_top(self) - (gchar *) entry) >> NV_TABLE_SCALE;
-  entry->vdirect.value_len_lo = value_len & 0xFFFF;
-  entry->vdirect.value_len_hi = value_len >> 16;
+  ofs = (nv_table_get_top(self) - (gchar *) entry);
+  entry->vdirect.value_len = value_len;
   if (handle >= self->num_static_entries)
     {
       /* we only store the name for non-builtin values */
@@ -465,11 +469,11 @@ nv_table_add_value(NVTable *self, NVHandle handle, const gchar *name, gsize name
 }
 
 gboolean
-nv_table_add_value_indirect(NVTable *self, NVHandle handle, const gchar *name, gsize name_len, NVHandle ref_handle, guint8 type, guint16 rofs, guint16 rlen, gboolean *new_entry)
+nv_table_add_value_indirect(NVTable *self, NVHandle handle, const gchar *name, gsize name_len, NVHandle ref_handle, guint8 type, guint32 rofs, guint32 rlen, gboolean *new_entry)
 {
   NVEntry *entry, *ref_entry;
-  guint32 *dyn_slot;
-  guint16 ofs;
+  NVDynValue *dyn_slot;
+  guint32 ofs;
 
   if (new_entry)
     *new_entry = FALSE;
@@ -513,7 +517,7 @@ nv_table_add_value_indirect(NVTable *self, NVHandle handle, const gchar *name, g
       if (!nv_table_foreach_entry(self, nv_table_make_direct, data))
         return FALSE;
     }
-  if (entry && (((guint) entry->alloc_len << NV_TABLE_SCALE) >= NV_ENTRY_INDIRECT_HDR + name_len + 1))
+  if (entry && (((guint) entry->alloc_len) >= NV_ENTRY_INDIRECT_HDR + name_len + 1))
     {
       /* this value already exists and the new reference  fits in the old space */
       ref_entry->referenced = TRUE;
@@ -548,7 +552,7 @@ nv_table_add_value_indirect(NVTable *self, NVHandle handle, const gchar *name, g
       return FALSE;
     }
 
-  ofs = (nv_table_get_top(self) - (gchar *) entry) >> NV_TABLE_SCALE;
+  ofs = (nv_table_get_top(self) - (gchar *) entry);
   entry->vindirect.handle = ref_handle;
   entry->vindirect.ofs = rofs;
   entry->vindirect.len = rlen;
@@ -564,6 +568,7 @@ nv_table_add_value_indirect(NVTable *self, NVHandle handle, const gchar *name, g
     entry->name_len = 0;
 
   nv_table_set_table_entry(self, handle, ofs, dyn_slot);
+
   return TRUE;
 }
 
@@ -592,7 +597,7 @@ nv_table_foreach(NVTable *self, NVRegistry *registry, NVTableForeachFunc func, g
 gboolean
 nv_table_foreach_entry(NVTable *self, NVTableForeachEntryFunc func, gpointer user_data)
 {
-  guint32 *dyn_entries;
+  NVDynValue *dyn_entries;
   NVEntry *entry;
   gint i;
 
@@ -633,11 +638,11 @@ nv_table_clear(NVTable *self)
 void
 nv_table_init(NVTable *self, gsize alloc_length, gint num_static_entries)
 {
-  g_assert(alloc_length <= NVTABLE_MAX_BYTES);
-  self->size = alloc_length >> NV_TABLE_SCALE;
+  g_assert(alloc_length <= NV_TABLE_MAX_BYTES);
+  self->size = alloc_length;
   self->used = 0;
   self->num_dyn_entries = 0;
-  self->num_static_entries = NV_TABLE_BOUND_NUM_STATIC(num_static_entries);
+  self->num_static_entries = num_static_entries;
   self->ref_cnt = 1;
   self->borrowed = FALSE;
   memset(&self->static_entries[0], 0, self->num_static_entries * sizeof(self->static_entries[0]));
@@ -677,33 +682,33 @@ nv_table_realloc(NVTable *self, NVTable **new)
 
   /* double the size of the current allocation */
   new_size = ((gsize) self->size) << 1;
-  if (new_size > NVTABLE_MAX_SIZE)
-    new_size = NVTABLE_MAX_SIZE;
+  if (new_size > NV_TABLE_MAX_BYTES)
+    new_size = NV_TABLE_MAX_BYTES;
   if (new_size == old_size)
     return FALSE;
 
   if (self->ref_cnt == 1 && !self->borrowed)
     {
-      *new = self = g_realloc(self, new_size << NV_TABLE_SCALE);
+      *new = self = g_realloc(self, new_size);
 
       self->size = new_size;
       /* move the downwards growing region to the end of the new buffer */
       memmove(NV_TABLE_ADDR(self, self->size - self->used),
               NV_TABLE_ADDR(self, old_size - self->used),
-              self->used << NV_TABLE_SCALE);
+              self->used);
     }
   else
     {
-      *new = g_malloc(new_size << NV_TABLE_SCALE);
+      *new = g_malloc(new_size);
 
       /* we only copy the header first */
-      memcpy(*new, self, sizeof(NVTable) + self->num_static_entries * sizeof(self->static_entries[0]) + self->num_dyn_entries * sizeof(guint32));
+      memcpy(*new, self, sizeof(NVTable) + self->num_static_entries * sizeof(self->static_entries[0]) + self->num_dyn_entries * sizeof(NVDynValue));
       (*new)->ref_cnt = 1;
       (*new)->borrowed = FALSE;
 
       memmove(NV_TABLE_ADDR((*new), (*new)->size - (*new)->used),
               NV_TABLE_ADDR(self, old_size - self->used),
-              self->used << NV_TABLE_SCALE);
+              self->used);
 
       nv_table_unref(self);
     }
@@ -742,16 +747,17 @@ nv_table_clone(NVTable *self, gint additional_space)
   if (nv_table_get_bottom(self) - nv_table_get_ofs_table_top(self) < additional_space)
     new_size = self->size;
   else
-    new_size = self->size + (NV_TABLE_BOUND(additional_space) >> NV_TABLE_SCALE);
+    new_size = self->size + (NV_TABLE_BOUND(additional_space));
 
-  new = g_malloc(new_size << NV_TABLE_SCALE);
-  memcpy(new, self, sizeof(NVTable) + self->num_static_entries * sizeof(self->static_entries[0]) + self->num_dyn_entries * sizeof(guint32));
+  new = g_malloc(new_size);
+  memcpy(new, self, sizeof(NVTable) + self->num_static_entries * sizeof(self->static_entries[0]) + self->num_dyn_entries * sizeof(NVDynValue));
   new->size = new_size;
   new->ref_cnt = 1;
   new->borrowed = FALSE;
 
   memcpy(NV_TABLE_ADDR(new, new->size - new->used),
           NV_TABLE_ADDR(self, self->size - self->used),
-          self->used << NV_TABLE_SCALE);
+          self->used);
+
   return new;
 }
diff --git a/lib/nvtable.h b/lib/nvtable.h
index 60366f3..621e7d0 100644
--- a/lib/nvtable.h
+++ b/lib/nvtable.h
@@ -29,12 +29,19 @@
 
 typedef struct _NVTable NVTable;
 typedef struct _NVRegistry NVRegistry;
+typedef struct _NVDynValue NVDynValue;
 typedef struct _NVEntry NVEntry;
-typedef guint16 NVHandle;
+typedef guint32 NVHandle;
 typedef struct _NVHandleDesc NVHandleDesc;
 typedef gboolean (*NVTableForeachFunc)(NVHandle handle, const gchar *name, const gchar *value, gssize value_len, gpointer user_data);
 typedef gboolean (*NVTableForeachEntryFunc)(NVHandle handle, NVEntry *entry, gpointer user_data);
 
+struct _NVDynValue
+{
+  NVHandle handle;
+  guint32 ofs;
+};
+
 struct _NVHandleDesc
 {
   gchar *name;
@@ -89,11 +96,6 @@ nv_registry_get_handle_name(NVRegistry *self, NVHandle handle, gssize *length)
   return stored->name;
 }
 
-/* size related values are stored in guint16 divided by 4 */
-#define NVTABLE_MAX_BYTES (65535 * 4)
-/* the maximum value for the size member */
-#define NVTABLE_MAX_SIZE  (65535)
-
 /*
  * Contains a name-value pair.
  */
@@ -102,21 +104,20 @@ struct _NVEntry
   /* negative offset, counting from string table top, e.g. start of the string is at @top + ofs */
   guint8 indirect:1, referenced:1;
   guint8 name_len;
-  guint16 alloc_len;
+  guint32 alloc_len;
   union
   {
     struct
     {
-      guint16 value_len_lo;
-      guint8  value_len_hi;
+      guint32 value_len;
       /* variable data, first the name of this entry, then the value, both are NUL terminated */
       gchar data[0];
     } vdirect;
     struct
     {
       NVHandle handle;
-      guint16 ofs;
-      guint16 len;
+      guint32 ofs;
+      guint32 len;
       guint8 type;
       gchar name[0];
     } vindirect;
@@ -151,15 +152,15 @@ nv_entry_get_name(NVEntry *self)
  * Name value area:
  *   - the name-value area grows down (e.g. lower addresses) from the end of the struct
  *   - name-value pairs are referenced by the offset counting down from the end of the struct
- *   - all NV pairs are positioned at 4 bytes boundary, thus we can index 256k with 16 bits (65536 << 2)
+ *   - all NV pairs are positioned at 4 bytes boundary, so 32 bit variables in NVEntry
+ *     can be accessed in an aligned manner
  *
  * Static value offsets:
- *   - a fixed size of guint16 array, containing 16 bit offsets for statically allocated entries
+ *   - a fixed size of guint32 array, containing 32 bit offsets for statically allocated entries
  *   - the handles for static values have a low value and they match the index in this array
  *
  * Dynamic values:
- *   - a dynamically sized guint32 array, the two high order bytes specify the global ID of the given value,
- *   - the low order 16 bits is the offset in this payload where
+ *   - a dynamically sized NVDynEntry array (contains ID + offset)
  *   - dynamic values are sorted by the global ID
  *
  * Memory allocation
@@ -183,8 +184,8 @@ nv_entry_get_name(NVEntry *self)
 struct _NVTable
 {
   /* byte order indication, etc. */
-  guint16 size;
-  guint16 used;
+  guint32 size;
+  guint32 used;
   guint16 num_dyn_entries;
   guint8 num_static_entries;
   guint8 ref_cnt:7,
@@ -194,20 +195,21 @@ struct _NVTable
   union
   {
     guint32 __dummy_for_alignment;
-    guint16 static_entries[0];
+    guint32 static_entries[0];
     gchar data[0];
   };
 };
 
-#define NV_TABLE_SCALE 2
 #define NV_TABLE_BOUND(x)  (((x) + 0x3) & ~0x3)
-#define NV_TABLE_ADDR(self, x) ((gchar *) ((self)) + ((x) << NV_TABLE_SCALE))
-#define NV_TABLE_ESTIMATE(value_num, string_sum)  ((value_num) * (sizeof(guint16) + sizeof(LogMessageStringTableEntry) + string_sum)
-#define NV_TABLE_BOUND_NUM_STATIC(x) ((x) & ~1)
+#define NV_TABLE_ADDR(self, x) ((gchar *) ((self)) + ((gssize)(x)))
+
 
+/* 256MB, this is an artificial limit, but must be less than MAX_GUINT32 as
+ * we want to compare a guint32 to this variable without overflow.  */
+#define NV_TABLE_MAX_BYTES  (256*1024*1024)
 
 gboolean nv_table_add_value(NVTable *self, NVHandle handle, const gchar *name, gsize name_len, const gchar *value, gsize value_len, gboolean *new_entry);
-gboolean nv_table_add_value_indirect(NVTable *self, NVHandle handle, const gchar *name, gsize name_len, NVHandle ref_handle, guint8 type, guint16 ofs, guint16 len, gboolean *new_entry);
+gboolean nv_table_add_value_indirect(NVTable *self, NVHandle handle, const gchar *name, gsize name_len, NVHandle ref_handle, guint8 type, guint32 ofs, guint32 len, gboolean *new_entry);
 
 gboolean nv_table_foreach(NVTable *self, NVRegistry *registry, NVTableForeachFunc func, gpointer user_data);
 gboolean nv_table_foreach_entry(NVTable *self, NVTableForeachEntryFunc func, gpointer user_data);
@@ -226,11 +228,11 @@ nv_table_get_alloc_size(gint num_static_entries, gint num_dyn_values, gint init_
   NVTable *self G_GNUC_UNUSED = NULL;
   gsize size;
 
-  size = NV_TABLE_BOUND(init_length) + NV_TABLE_BOUND(sizeof(NVTable) + num_static_entries * sizeof(self->static_entries[0]) + num_dyn_values * sizeof(guint32));
+  size = NV_TABLE_BOUND(init_length) + NV_TABLE_BOUND(sizeof(NVTable) + num_static_entries * sizeof(self->static_entries[0]) + num_dyn_values * sizeof(NVDynValue));
   if (size < 128)
     return 128;
-  if (size > NVTABLE_MAX_BYTES)
-    size = NVTABLE_MAX_BYTES;
+  if (size > NV_TABLE_MAX_BYTES)
+    size = NV_TABLE_MAX_BYTES;
   return size;
 }
 
@@ -241,14 +243,14 @@ nv_table_get_top(NVTable *self)
 }
 
 /* private declarations for inline functions */
-NVEntry *nv_table_get_entry_slow(NVTable *self, NVHandle handle, guint32 **dyn_slot);
+NVEntry *nv_table_get_entry_slow(NVTable *self, NVHandle handle, NVDynValue **dyn_slot);
 const gchar *nv_table_resolve_indirect(NVTable *self, NVEntry *entry, gssize *len);
 
 
 static inline NVEntry *
-__nv_table_get_entry(NVTable *self, NVHandle handle, guint16 num_static_entries, guint32 **dyn_slot)
+__nv_table_get_entry(NVTable *self, NVHandle handle, guint16 num_static_entries, NVDynValue **dyn_slot)
 {
-  guint16 ofs;
+  guint32 ofs;
 
   if (G_UNLIKELY(!handle))
     {
@@ -262,7 +264,7 @@ __nv_table_get_entry(NVTable *self, NVHandle handle, guint16 num_static_entries,
       *dyn_slot = NULL;
       if (G_UNLIKELY(!ofs))
         return NULL;
-      return (NVEntry *) (nv_table_get_top(self) - (ofs << NV_TABLE_SCALE));
+      return (NVEntry *) (nv_table_get_top(self) - ofs);
     }
   else
     {
@@ -271,7 +273,7 @@ __nv_table_get_entry(NVTable *self, NVHandle handle, guint16 num_static_entries,
 }
 
 static inline NVEntry *
-nv_table_get_entry(NVTable *self, NVHandle handle, guint32 **dyn_slot)
+nv_table_get_entry(NVTable *self, NVHandle handle, NVDynValue **dyn_slot)
 {
   return __nv_table_get_entry(self, handle, self->num_static_entries, dyn_slot);
 }
@@ -280,7 +282,7 @@ static inline const gchar *
 __nv_table_get_value(NVTable *self, NVHandle handle, guint16 num_static_entries, gssize *length)
 {
   NVEntry *entry;
-  guint32 *dyn_slot;
+  NVDynValue *dyn_slot;
 
   entry = nv_table_get_entry(self, handle, &dyn_slot);
   if (G_UNLIKELY(!entry))
@@ -293,7 +295,7 @@ __nv_table_get_value(NVTable *self, NVHandle handle, guint16 num_static_entries,
   if (!entry->indirect)
     {
       if (length)
-        *length = entry->vdirect.value_len_lo + (entry->vdirect.value_len_hi << 16);
+        *length = entry->vdirect.value_len;
       return entry->vdirect.data + entry->name_len + 1;
     }
   return nv_table_resolve_indirect(self, entry, length);
diff --git a/tests/unit/test_nvtable.c b/tests/unit/test_nvtable.c
index 9f17cf7..3bfa009 100644
--- a/tests/unit/test_nvtable.c
+++ b/tests/unit/test_nvtable.c
@@ -365,7 +365,7 @@ test_nvtable_indirect()
   /* NOTE: the sizing of the NVTable can easily be broken, it is sized
      to make it possible to store one direct entry */
 
-  tab = nv_table_new(STATIC_VALUES, 0, 138);
+  tab = nv_table_new(STATIC_VALUES, 0, 138+3);  // direct: +3
   success = nv_table_add_value(tab, STATIC_HANDLE, STATIC_NAME, 4, value, 128, NULL);
   TEST_ASSERT(success == TRUE);
 
@@ -437,7 +437,7 @@ test_nvtable_indirect()
   /* the new entry will not fit to the space allocated to the old and neither to the NVTable */
 
   /* setup code: add static and a dynamic-direct entry */
-  tab = nv_table_new(STATIC_VALUES, 1, 154);
+  tab = nv_table_new(STATIC_VALUES, 1, 154+3+4);  // direct: +3, indirect: +4
   success = nv_table_add_value(tab, STATIC_HANDLE, STATIC_NAME, 4, value, 128, NULL);
   TEST_ASSERT(success == TRUE);
   success = nv_table_add_value(tab, handle, name, strlen(name), value, 1, NULL);
@@ -535,7 +535,7 @@ test_nvtable_indirect()
 
   /* one that is too large */
 
-  tab = nv_table_new(STATIC_VALUES, STATIC_VALUES, 256);
+  tab = nv_table_new(STATIC_VALUES, 4, 256);
   success = nv_table_add_value(tab, STATIC_HANDLE, STATIC_NAME, 4, value, 128, NULL);
   TEST_ASSERT(success == TRUE);
   success = nv_table_add_value_indirect(tab, DYN_HANDLE, DYN_NAME, strlen(DYN_NAME), STATIC_HANDLE, 0, 1, 126, NULL);
@@ -600,7 +600,7 @@ test_nvtable_indirect()
 
   /* one that is too large */
 
-  tab = nv_table_new(STATIC_VALUES, STATIC_VALUES, 256);
+  tab = nv_table_new(STATIC_VALUES, 4, 256);
   success = nv_table_add_value(tab, STATIC_HANDLE, STATIC_NAME, 4, value, 128, NULL);
   TEST_ASSERT(success == TRUE);
   success = nv_table_add_value_indirect(tab, DYN_HANDLE, DYN_NAME, strlen(DYN_NAME), STATIC_HANDLE, 0, 1, 126, NULL);
-- 
1.7.2.5


--------------080206030106010302040206
Content-Type: text/plain;
 name="0002-syslog-source-make-buffer-dynamically-allocated.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename*0="0002-syslog-source-make-buffer-dynamically-allocated.patch"



More information about the syslog-ng mailing list