]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Split alist/ilist
authorEric Bollengier <eric@baculasystems.com>
Fri, 5 Feb 2021 08:57:12 +0000 (09:57 +0100)
committerEric Bollengier <eric@baculasystems.com>
Fri, 5 Feb 2021 21:23:44 +0000 (22:23 +0100)
ilist and alist are a bit different on some aspects, it's
better to split them waiting to fix ilist usage in the cloud
module.

bacula/src/lib/Makefile.in
bacula/src/lib/alist.c
bacula/src/lib/alist.h
bacula/src/lib/ilist.c [new file with mode: 0644]
bacula/src/lib/ilist.h [new file with mode: 0644]
bacula/src/lib/lib.h

index a6547181744f7dcacc87226aa08f9cb9716def5c..5ee28d8958305081525b4378b3bf3f78a8c2ccfe 100644 (file)
@@ -45,7 +45,7 @@ INCLUDE_FILES = ../baconfig.h ../bacula.h ../bc_types.h \
       waitq.h watchdog.h workq.h \
       parse_conf.h ini.h \
       worker.h lockmgr.h devlock.h output.h bwlimit.h \
-      collect.h event.h
+      collect.h event.h ilist.h
 
 #
 # libbac
@@ -62,7 +62,7 @@ LIBBAC_SRCS = attr.c base64.c berrno.c bsys.c binflate.c bget_msg.c \
       util.c var.c watchdog.c workq.c btimers.c \
       worker.c flist.c bcollector.c collect.c \
       address_conf.c breg.c htable.c lockmgr.c devlock.c output.c bwlimit.c \
-      bsock_meeting.c bcrc32.c events.c $(EXTRA_SRCS)
+      bsock_meeting.c bcrc32.c events.c ilist.c $(EXTRA_SRCS)
 
 LIBBAC_OBJS_TMP = $(LIBBAC_SRCS:.c=.o)
 LIBBAC_OBJS = $(LIBBAC_OBJS_TMP:.cc=.o)
@@ -230,6 +230,14 @@ alist_test: Makefile libbac.la alist.c unittests.o
        $(RMF) alist.o
        $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) alist.c
 
+ilist_test: Makefile libbac.la ilist.c unittests.o
+       $(RMF) ilist.o
+       $(CXX) -DTEST_PROGRAM $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) ilist.c
+       $(LIBTOOL_LINK) $(CXX) $(LDFLAGS) -L. -o $@ ilist.o unittests.o $(DLIB) -lbac -lm $(LIBS) $(OPENSSL_LIBS)
+       $(LIBTOOL_INSTALL) $(INSTALL_PROGRAM) $@ $(DESTDIR)$(sbindir)/
+       $(RMF) ilist.o
+       $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) ilist.c
+
 dlist_test: Makefile libbac.la dlist.c unittests.o
        $(RMF) dlist.o
        $(CXX) -DTEST_PROGRAM $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) dlist.c
index 81f60aba7ccab4bd068fd62ab3b7d20d0e4eed4b..1a36eed4145431f8adf516e640d3e06f44f828e1 100644 (file)
@@ -45,7 +45,8 @@ void baselist::grow_list()
    int new_max_items;
 
    /* put() can insert and item anywhere in the list so
-   it's important to allocate at least last_item+1 items */
+    * it's important to allocate at least last_item+1 items 
+    */
    int min_grow = MAX(10, last_item+1);
    if (num_grow < min_grow) {
       num_grow = min_grow;               /* default if not initialized */
@@ -126,7 +127,6 @@ void alist::prepend(void *item)
    last_item++;
 }
 
-
 /*
  * Append an item to the list
  */
@@ -137,22 +137,6 @@ void baselist::append(void *item)
    num_items++;
 }
 
-/*
- * Put an item at a particular index
- */
-void ilist::put(int index, void *item)
-{
-   if (index > last_item) {
-      last_item = index;
-   }
-   grow_list();
-   if (items[index] == NULL) {
-      num_items++;
-   }
-   items[index] = item;
-}
-
-
 /*
  * Remove an item from the list
  * Note: you must free the item when
@@ -220,34 +204,36 @@ struct FILESET {
    alist mylist;
 };
 
-void check_all_alist_contents(alist *mlist)
+void check_all_alist_indexes2(alist *mlist)
 {
    bool check_cont = true;
-   char buf[30];
-   int i;
+   char *bp;
+   int i = 0;
+   int nb;
 
-   for (i = 0; i < mlist->size(); i++) {
-      sprintf(buf, "This is item %d", i);
-      if (strcmp(buf, (char*)mlist->get(i)) != 0){
+   foreach_alist_index(i, bp, mlist) {
+      nb = atoi(bp);
+      if (nb != i){
+         Dmsg2(0, "nb=%d != i=%d\n", nb, i);
          check_cont = false;
       }
    }
-   ok(check_cont, "Checking alist contents");
+   ok(check_cont, "Check all alist indexes 2");
 };
 
-void check_all_ilist_contents(ilist *vlist, int start)
+void check_all_alist_contents(alist *mlist)
 {
    bool check_cont = true;
    char buf[30];
    int i;
 
-   for (i = start; i< vlist->size(); i++) {
+   for (i = 0; i < mlist->size(); i++) {
       sprintf(buf, "This is item %d", i);
-      if (strcmp(buf, (char*)vlist->get(i)) != 0){
+      if (strcmp(buf, (char*)mlist->get(i)) != 0){
          check_cont = false;
       }
    }
-   ok(check_cont, "Checking ilist contents");
+   ok(check_cont, "Checking alist contents");
 };
 
 void check_all_alist_indexes(alist *mlist)
@@ -274,33 +260,25 @@ void check_alist_destroy_and_delete(alist *mlist)
    delete mlist;
 };
 
-void check_ilist_destroy_delete(ilist *vlist)
-{
-   vlist->destroy();
-   ok(vlist->size() == 0, "Check ilist size after destroy");
-   delete vlist;
-}
-
 int main()
 {
    Unittests alist_test("alist_test");
    FILESET *fileset;
    char buf[30];
    alist *mlist;
-   ilist *vlist;
    char *bp;
    int i;
    bool check_cont;
    bool check_indx;
 
-   Pmsg0(0, "Initialize tests ...\n");
+   log("Initialize tests ...");
    fileset = (FILESET *)malloc(sizeof(FILESET));
    bmemzero(fileset, sizeof(FILESET));
    fileset->mylist.init();
    ok(fileset && fileset->mylist.empty() && fileset->mylist.max_size() == 0,
       "Default initialization");
 
-   Pmsg0(0, "Automatic allocation/destruction of alist:\n");
+   log("Automatic allocation/destruction of alist:");
 
    for (int i = 0; i < NUMITEMS; i++) {
       sprintf(buf, "This is item %d", i);
@@ -309,12 +287,13 @@ int main()
    ok(fileset->mylist.size() == NUMITEMS, "Checking size");
 
    check_all_alist_contents(&fileset->mylist);
+
    fileset->mylist.destroy();
    ok(fileset->mylist.size() == 0, "Check size after delete");
    ok(fileset->mylist.last() == NULL, "Check last after delete");
    free(fileset);
 
-   Pmsg0(0, "Allocation/destruction using new delete\n");
+   log("Allocation/destruction using new delete");
 
    mlist = New(alist(50));
    ok(mlist && mlist->empty() && mlist->max_size() == 0,
@@ -327,7 +306,7 @@ int main()
    check_all_alist_contents(mlist);
    check_alist_destroy_and_delete(mlist);
 
-   Pmsg0(0, "Test alist::remove(0)\n");
+   log("Test alist::remove(0)");
    mlist = New(alist(10, owned_by_alist));
    mlist->append(bstrdup("trash"));
    mlist->append(bstrdup("0"));
@@ -342,7 +321,7 @@ int main()
    check_all_alist_indexes(mlist);
    check_alist_destroy_and_delete(mlist);
 
-   Pmsg0(0, "Test alist::remove(3)\n");
+   log("Test alist::remove(3)");
    mlist = New(alist(10, owned_by_alist));
    mlist->append(bstrdup("0"));
    mlist->append(bstrdup("1"));
@@ -357,7 +336,7 @@ int main()
    check_all_alist_indexes(mlist);
    check_alist_destroy_and_delete(mlist);
 
-   Pmsg0(0, "Test alist::remove(last)\n");
+   log("Test alist::remove(last)");
    mlist = New(alist(10, owned_by_alist));
    mlist->append(bstrdup("0"));
    mlist->append(bstrdup("1"));
@@ -371,21 +350,23 @@ int main()
    check_all_alist_indexes(mlist);
    check_alist_destroy_and_delete(mlist);
 
-   Pmsg0(0, "Test alist::remove(last+1)\n");
+   log("Test alist::remove(last+1)");
    mlist = New(alist(10, owned_by_alist));
    mlist->append(bstrdup("0"));
    mlist->append(bstrdup("1"));
    mlist->append(bstrdup("2"));
    mlist->append(bstrdup("3"));
    mlist->append(bstrdup("4"));
+   check_all_alist_indexes2(mlist);
    ok(mlist && mlist->size() == 5, "Checking size");
    ok(mlist->last_index() == 5, "Check last_index");
    ok(mlist->remove(5) == NULL, "Check remove returns null");
    ok(mlist->size() == 5, "Remove test size");
    check_all_alist_indexes(mlist);
+   check_all_alist_indexes2(mlist);   
    check_alist_destroy_and_delete(mlist);
 
-   Pmsg0(0, "Test alist::pop()\n");
+   log("Test alist::pop()");
    mlist = New(alist(10, owned_by_alist));
    mlist->append(bstrdup("0"));
    mlist->append(bstrdup("1"));
@@ -399,37 +380,7 @@ int main()
    check_all_alist_indexes(mlist);
    check_alist_destroy_and_delete(mlist);
 
-   Pmsg0(0, "Test ilist::put()\n");
-   vlist = New(ilist(10, owned_by_alist));
-   sprintf(buf, "This is item 10");
-   vlist->put(10, bstrdup(buf));
-   ok(vlist && vlist->size() == 1, "Checking size after put()");
-   ok(vlist->last_index() == 10, "Check last_index");
-   check_ilist_destroy_delete(vlist);
-
-   Pmsg0(0, "Test ilist with multiple put()\n");
-   vlist = New(ilist(50, owned_by_alist));
-   sprintf(buf, "This is item 10");
-   vlist->put(10, bstrdup(buf));
-   ok(vlist && vlist->size() == 1, "Checking size after put()");
-   ok(vlist->last_index() == 10, "Check last_index");
-   sprintf(buf, "This is item 15");
-   vlist->put(15, bstrdup(buf));
-   ok(vlist->size() == 2, "Checking size after put()");
-   ok(vlist->last_index() == 15, "Check last_index");
-   for (i = NUMITEMS; i < NUMITEMS + MORENUMITEMS; i++) {
-      sprintf(buf, "This is item %d", i);
-      vlist->put(i, bstrdup(buf));
-   }
-   ok(vlist->size() == 2 + MORENUMITEMS, "Checking size after put()");
-   ok(vlist->last_index() == NUMITEMS + MORENUMITEMS - 1, "Check last_index");
-   /* check contents, first two sparse elements */
-   ok(strcmp("This is item 10", (char *)vlist->get(10)) == 0, "Check ilist content at 10");
-   ok(strcmp("This is item 15", (char *)vlist->get(15)) == 0, "Check ilist content at 15");
-   check_all_ilist_contents(vlist, NUMITEMS);
-   check_ilist_destroy_delete(vlist);
-
-   Pmsg0(0, "Test alist::push()\n");
+   log("Test alist::push()");
    mlist = New(alist(10, owned_by_alist));
    check_cont = true;
    check_indx = true;
@@ -445,7 +396,7 @@ int main()
    }
    ok(check_cont, "Check all sizes after push");
    ok(check_indx, "Check all last_indexes after push");
-   Pmsg0(0, "Test alist::pop()\n");
+   log("Test alist::pop()");
    check_cont = true;
    for (i = NUMITEMS-1; (bp = (char *)mlist->pop()); i--) {
       sprintf(buf, "This is item %d", i);
@@ -468,6 +419,26 @@ int main()
    ok(check_cont, "Check get() after pop() contents.");
    check_alist_destroy_and_delete(mlist);
 
+   log("Test alist::foreach_alist_index()");
+   mlist = New(alist(10, owned_by_alist));
+   mlist->append(bstrdup("0"));
+   mlist->append(bstrdup("1"));
+   mlist->append(bstrdup("2"));
+   mlist->append(bstrdup("3"));
+   mlist->append(bstrdup("4"));
+   mlist->append(bstrdup("5"));
+   mlist->append(bstrdup("6"));
+   mlist->append(bstrdup("7"));
+   mlist->append(bstrdup("8"));
+   mlist->append(bstrdup("9"));
+   check_all_alist_indexes2(mlist);
+   ok(mlist && mlist->size() == 10, "Checking size");
+   ok(mlist->last_index() == 10, "Check last_index");
+   foreach_alist_index(i, bp, mlist) {
+      ok(i < mlist->size(), "check index");
+      ok(bp != NULL, "check element of alist");
+   }
+   check_alist_destroy_and_delete(mlist);
    return report();
 }
 #endif
index 12f50f2dd40f798e0f72228254f47de2beaf6e1f..3a86867d34b59f7171d3fb6e386a2d28e2bff4f0 100644 (file)
@@ -20,6 +20,8 @@
  *  Kern Sibbald, June MMIII
  */
 
+#ifndef ALIST_H
+#define ALIST_H
 
 extern bool is_null(const void *ptr);
 
@@ -66,7 +68,9 @@ class baselist : public SMARTALLOC {
 protected:
    void **items;                /* from  0..n-1 */
    int num_items;               /* from  1..n   */
-   int last_item;               /* maximum item index (1..n) */
+
+   int last_item;               /* maximum item index (1..n). */
+
    int max_items;               /* maximum possible items (array size) (1..n) */
    int num_grow;
    int cur_item;                /* from 1..n */
@@ -105,17 +109,6 @@ public:
    void *remove(int index) { return remove_item(index);};
 };
 
-/*
- * Indexed list -- much like a simplified STL vector
- *   array of pointers to inserted items
- */
-class ilist : public baselist {
-public:
-   ilist(int num = 100, bool own=true): baselist(num, own) {};
-    /* put() is not compatible with remove(), prepend() or foreach_alist */
-   void put(int index, void *item);
-};
-
 /*
  * Define index operator []
  */
@@ -170,3 +163,5 @@ inline void baselist::grow(int num)
 {
    num_grow = num;
 }
+
+#endif // ALIST_H
diff --git a/bacula/src/lib/ilist.c b/bacula/src/lib/ilist.c
new file mode 100644 (file)
index 0000000..f75648f
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+   Bacula(R) - The Network Backup Solution
+
+   Copyright (C) 2000-2020 Kern Sibbald
+
+   The original author of Bacula is Kern Sibbald, with contributions
+   from many others, a complete list can be found in the file AUTHORS.
+
+   You may use this file and others of this release according to the
+   license defined in the LICENSE file, which includes the Affero General
+   Public License, v3.0 ("AGPLv3") and some additional permissions and
+   terms pursuant to its AGPLv3 Section 7.
+
+   This notice must be preserved when any source code is
+   conveyed and/or propagated.
+
+   Bacula(R) is a registered trademark of Kern Sibbald.
+*/
+/*
+ *  Bacula array list routines
+ *
+ *    ilist is a simple malloc'ed array of pointers.  For the moment,
+ *      it simply malloc's a bigger array controlled by num_grow.
+ *      Default is to realloc the pointer array for each new member.
+ *
+ *    Note: the list can have holes (empty items). This is done by
+ *      using get() and put().
+ *
+ *   From alist.c
+ *
+ */
+
+#include "bacula.h"
+
+/*
+ * Private grow list function. Used to insure that
+ *   at least one more "slot" is available.
+ */
+void ilist::grow_list()
+{
+   int i;
+   int new_max_items;
+
+   /* put() can insert and item anywhere in the list so
+    * it's important to allocate at least last_item+1 items 
+    */
+   int min_grow = MAX(10, last_item+1);
+   if (num_grow < min_grow) {
+      num_grow = min_grow;               /* default if not initialized */
+   }
+
+   if (items == NULL) {
+      items = (void **)malloc(num_grow * sizeof(void *));
+      for (i=0; i<num_grow; i++) {
+         items[i] = NULL;
+      }
+      max_items = num_grow;
+   } else if (last_item >= max_items) {
+      new_max_items = last_item + num_grow;
+      items = (void **)realloc(items, new_max_items * sizeof(void *));
+      for (i=max_items; i<new_max_items; i++) {
+         items[i] = NULL;
+      }
+      max_items = new_max_items;
+   }
+}
+
+void ilist::append(void *item)
+{
+   grow_list();
+   items[last_item++] = item;
+   num_items++;
+}
+
+/*
+ * Put an item at a particular index
+ */
+void ilist::put(int index, void *item)
+{
+   if (index > last_item) {
+      last_item = index; // FIXME: On alist, last_item is pointing after the last item
+   }
+   grow_list();
+   if (items[index] == NULL) {
+      num_items++;
+   }
+   items[index] = item;
+}
+
+
+/*
+ * Remove an item from the list
+ * Note: you must free the item when
+ *   you are done with it.
+ */
+void * ilist::remove_item(int index)
+{
+   void *item;
+   if (index < 0 || index >= last_item) {
+      return NULL;
+   }
+   item = items[index];
+
+   /* last_item is from 1..n, we work from 0..n-1 */
+   for (int i=index; i < (last_item-1); i++) {
+      items[i] = items[i+1];
+   }
+
+   items[last_item-1] = NULL;   /* The last item is shifted by one, the last slot is always free */
+
+   last_item--;                 /* We have shifted all items by 1 */
+   num_items--;                 /* We have 1 item less */
+
+   return item;
+}
+
+
+/* Get the index item -- we should probably allow real indexing here */
+void * ilist::get(int index)
+{
+   if (items == NULL || index < 0 || index > last_item) { // Difference with alist here
+      return NULL;
+   }
+   return items[index];
+}
+
+/* Destroy the list and its contents */
+void ilist::destroy()
+{
+   if (items) {
+      if (own_items) {
+         for (int i=0; i<max_items; i++) {
+            if (items[i]) {
+               bfree(items[i]);
+               items[i] = NULL;
+            }
+         }
+      }
+      bfree(items);
+      items = NULL;
+   }
+   num_items = 0;
+   last_item = 0;
+   max_items = 0;
+   num_grow = 0;
+}
+
+#ifdef TEST_PROGRAM
+#include "unittests.h"
+
+#define NUMITEMS        20
+#define MORENUMITEMS    115
+
+void check_all_ilist_contents(ilist *vlist, int start)
+{
+   bool check_cont = true;
+   char buf[30];
+   int i;
+
+   for (i = start; i< vlist->size(); i++) {
+      sprintf(buf, "This is item %d", i);
+      if (strcmp(buf, (char*)vlist->get(i)) != 0){
+         check_cont = false;
+      }
+   }
+   ok(check_cont, "Checking ilist contents");
+};
+
+void check_ilist_destroy_delete(ilist *vlist)
+{
+   vlist->destroy();
+   ok(vlist->size() == 0, "Check ilist size after destroy");
+   delete vlist;
+}
+
+int main()
+{
+   Unittests ilist_test("ilist_test");
+   char buf[30];
+   ilist *vlist;
+   char *bp;
+   int i;
+   bool check_cont;
+   bool check_indx;
+
+   log("Initialize tests ...");
+   log("Test ilist::put()");
+   vlist = New(ilist(10, owned_by_ilist));
+   sprintf(buf, "This is item 10");
+   vlist->put(10, bstrdup(buf));
+   ok(vlist && vlist->size() == 1, "Checking size after put()");
+   ok(vlist->last_index() == 10, "Check last_index");
+   check_ilist_destroy_delete(vlist);
+
+   log("Test ilist with multiple put()");
+   vlist = New(ilist(50, owned_by_ilist));
+   sprintf(buf, "This is item 10");
+   vlist->put(10, bstrdup(buf));
+   ok(vlist && vlist->size() == 1, "Checking size after put()");
+   ok(vlist->last_index() == 10, "Check last_index");
+   sprintf(buf, "This is item 15");
+   vlist->put(15, bstrdup(buf));
+   ok(vlist->size() == 2, "Checking size after put()");
+   ok(vlist->last_index() == 15, "Check last_index");
+   for (i = NUMITEMS; i < NUMITEMS + MORENUMITEMS; i++) {
+      sprintf(buf, "This is item %d", i);
+      vlist->put(i, bstrdup(buf));
+   }
+   ok(vlist->size() == 2 + MORENUMITEMS, "Checking size after put()");
+   ok(vlist->last_index() == NUMITEMS + MORENUMITEMS - 1, "Check last_index");
+   /* check contents, first two sparse elements */
+   ok(strcmp("This is item 10", (char *)vlist->get(10)) == 0, "Check ilist content at 10");
+   ok(strcmp("This is item 15", (char *)vlist->get(15)) == 0, "Check ilist content at 15");
+   check_all_ilist_contents(vlist, NUMITEMS);
+   check_ilist_destroy_delete(vlist);
+
+   return report();
+}
+#endif
diff --git a/bacula/src/lib/ilist.h b/bacula/src/lib/ilist.h
new file mode 100644 (file)
index 0000000..7ae3bc7
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+   Bacula(R) - The Network Backup Solution
+
+   Copyright (C) 2000-2020 Kern Sibbald
+
+   The original author of Bacula is Kern Sibbald, with contributions
+   from many others, a complete list can be found in the file AUTHORS.
+
+   You may use this file and others of this release according to the
+   license defined in the LICENSE file, which includes the Affero General
+   Public License, v3.0 ("AGPLv3") and some additional permissions and
+   terms pursuant to its AGPLv3 Section 7.
+
+   This notice must be preserved when any source code is
+   conveyed and/or propagated.
+
+   Bacula(R) is a registered trademark of Kern Sibbald.
+*/
+
+#ifndef ILIST_H
+#define ILIST_H
+
+extern bool is_null(const void *ptr);
+
+/* Second arg of init */
+enum {
+  owned_by_ilist = true,
+  not_owned_by_ilist = false
+};
+
+/*
+ * Array list -- much like a simplified STL vector
+ *   array of pointers to inserted items. 
+ */
+class ilist : public SMARTALLOC {
+protected:
+   void **items;                /* from  0..n-1 */
+   int num_items;               /* from  1..n   */
+
+   int last_item;               /* maximum item index (1..n). */
+
+   int max_items;               /* maximum possible items (array size) (1..n) */
+   int num_grow;
+   int cur_item;                /* from 1..n */
+   bool own_items;
+   void grow_list(void);
+   void *remove_item(int index);
+
+public:
+   ilist(int num = 100, bool own=true);
+   ~ilist();
+   void init(int num = 100, bool own=true);
+   void append(void *item);
+   void *get(int index);
+   bool empty() const;
+   int last_index() const { return last_item; };
+   int max_size() const { return max_items; };
+   void * operator [](int index) const;
+   int size() const;
+   void destroy();
+   void grow(int num);
+
+   void put(int index, void *item);
+};
+
+inline bool ilist::empty() const
+{
+   return num_items == 0;
+}
+
+/*
+ * This allows us to do explicit initialization,
+ *   allowing us to mix C++ classes inside malloc'ed
+ *   C structures. Define before called in constructor.
+ */
+inline void ilist::init(int num, bool own)
+{
+   items = NULL;
+   num_items = 0;
+   last_item = 0;
+   max_items = 0;
+   num_grow = num;
+   own_items = own;
+}
+
+/*
+ * Define index operator []
+ */
+inline void * ilist::operator [](int index) const {
+   if (index < 0 || index >= max_items) {
+      return NULL;
+   }
+   return items[index];
+}
+
+/* Constructor */
+inline ilist::ilist(int num, bool own)
+{
+   init(num, own);
+}
+
+/* Destructor */
+inline ilist::~ilist()
+{
+   destroy();
+}
+
+/* Current size of list */
+inline int ilist::size() const
+{
+   return num_items;
+}
+
+/* How much to grow by each time */
+inline void ilist::grow(int num)
+{
+   num_grow = num;
+}
+
+#endif  // ILIST_H
index a5158bebbc4873e6517a7022ce66b9ff4c41e857..ea5c020fa8a50d79492d654e966f70023794c349 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "smartall.h"
 #include "lockmgr.h"
+#include "ilist.h"
 #include "alist.h"
 #include "dlist.h"
 #include "flist.h"