]> mj.ucw.cz Git - libucw.git/commitdiff
Growing arrays now support auto-zeroing mode
authorMartin Mares <mj@ucw.cz>
Fri, 10 Feb 2012 21:57:03 +0000 (22:57 +0100)
committerMartin Mares <mj@ucw.cz>
Fri, 10 Feb 2012 21:57:03 +0000 (22:57 +0100)
TODO
ucw/gary.c
ucw/gary.h

diff --git a/TODO b/TODO
index 2e63b0cdcc191b5fff7d547cb32873ceca252b13..688e7b60a2f3da5d7f706bd3ec6a15436b5e9296 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,5 +1,4 @@
 - Clean up free/
-- gary: Add automatic zeroing
 - Remove sighandler.[ch]
 - ipaccess: support IPv6
 - lfs-test: generalize or kill
index 801981ae1d9d30fd408833456e1e7c467b74a86c..579d6ab1d85cb264001967af8c9f79199441976f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     UCW Library -- A simple growing array of an arbitrary type
  *
- *     (c) 2010 Martin Mares <mj@ucw.cz>
+ *     (c) 2010--2012 Martin Mares <mj@ucw.cz>
  */
 
 #undef LOCAL_DEBUG
@@ -9,14 +9,19 @@
 #include "ucw/lib.h"
 #include "ucw/gary.h"
 
+#include <string.h>
+
 void *
-gary_init(size_t elt_size, size_t num_elts)
+gary_init(size_t elt_size, size_t num_elts, int zeroed)
 {
   DBG("GARY: Init to %zd elements", num_elts);
   struct gary_hdr *h = xmalloc(GARY_HDR_SIZE + elt_size * num_elts);
   h->num_elts = h->have_space = num_elts;
   h->elt_size = elt_size;
-  return (byte *)h + GARY_HDR_SIZE;
+  h->zeroed = zeroed;
+  if (zeroed)
+    bzero(GARY_BODY(h), elt_size * num_elts);
+  return GARY_BODY(h);
 }
 
 void
@@ -28,12 +33,16 @@ gary_free(void *array)
 static struct gary_hdr *
 gary_realloc(struct gary_hdr *h, size_t n)
 {
+  size_t old_size = h->have_space;
   if (n > 2*h->have_space)
     h->have_space = n;
   else
     h->have_space *= 2;
-  DBG("GARY: Resize to %zd elements (need %zd)", h->have_space, n);
-  return xrealloc(h, GARY_HDR_SIZE + h->have_space * h->elt_size);
+  DBG("GARY: Resize from %zd to %zd elements (need %zd)", old_size, h->have_space, n);
+  h = xrealloc(h, GARY_HDR_SIZE + h->have_space * h->elt_size);
+  if (h->zeroed)
+    bzero(GARY_BODY(h) + h->elt_size * old_size, h->elt_size * (h->have_space - old_size));
+  return h;
 }
 
 void *
@@ -76,11 +85,15 @@ gary_fix(void *array)
 int main(void)
 {
   int *a;
-  GARY_INIT(a, 5);
+  GARY_INIT_ZERO(a, 5);
 
   for (int i=0; i<5; i++)
-    a[i] = i+1;
+    {
+      ASSERT(!a[i]);
+      a[i] = i+1;
+    }
 
+  GARY_PUSH(a, 1);
   *GARY_PUSH(a, 1) = 10;
   *GARY_PUSH(a, 1) = 20;
   *GARY_PUSH(a, 1) = 30;
index 89760ffc65c8b1d09cffa73aeb313bcbd2a645ec..942f9b9c95bd30a8f5b394419e29af4ad46cbf76 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     UCW Library -- A simple growing array of an arbitrary type
  *
- *     (c) 2010 Martin Mares <mj@ucw.cz>
+ *     (c) 2010--2012 Martin Mares <mj@ucw.cz>
  */
 
 #ifndef _UCW_GARY_H
@@ -11,13 +11,15 @@ struct gary_hdr {
   size_t num_elts;
   size_t have_space;
   size_t elt_size;
+  int zeroed;
 };
 
 #define GARY_HDR_SIZE ALIGN_TO(sizeof(struct gary_hdr), CPU_STRUCT_ALIGN)
 #define GARY_HDR(ptr) ((struct gary_hdr *)((byte*)(ptr) - GARY_HDR_SIZE))
 #define GARY_BODY(ptr) ((byte *)(ptr) + GARY_HDR_SIZE)
 
-#define GARY_INIT(ptr, n) (ptr) = gary_init(sizeof(*(ptr)), (n))
+#define GARY_INIT(ptr, n) (ptr) = gary_init(sizeof(*(ptr)), (n), 0)
+#define GARY_INIT_ZERO(ptr, n) (ptr) = gary_init(sizeof(*(ptr)), (n), 1)
 #define GARY_FREE(ptr) do { if (ptr) xfree(GARY_HDR(ptr)); } while (0)
 #define GARY_SIZE(ptr) (GARY_HDR(ptr)->num_elts)
 #define GARY_RESIZE(ptr, n) (ptr) = gary_set_size((ptr), (n))
@@ -36,7 +38,7 @@ struct gary_hdr {
 #define GARY_FIX(ptr) (ptr) = gary_fix((ptr))
 
 /* Internal functions */
-void *gary_init(size_t elt_size, size_t num_elts);
+void *gary_init(size_t elt_size, size_t num_elts, int zeroed);
 void gary_free(void *array);
 void *gary_set_size(void *array, size_t n);
 void *gary_push_helper(void *array, size_t n, byte **cptr);