Author: sewardj
Date: 2007-09-26 23:45:14 +0100 (Wed, 26 Sep 2007)
New Revision: 6914

Log:
Use the underlying WordFM machinery to implement bags (multisets) of
(unboxed) words.

Modified:
   branches/THRCHECK/thrcheck/tc_wordfm.c
   branches/THRCHECK/thrcheck/tc_wordfm.h


Modified: branches/THRCHECK/thrcheck/tc_wordfm.c
===================================================================
--- branches/THRCHECK/thrcheck/tc_wordfm.c      2007-09-26 22:31:05 UTC (rev 
6913)
+++ branches/THRCHECK/thrcheck/tc_wordfm.c      2007-09-26 22:45:14 UTC (rev 
6914)
@@ -67,7 +67,7 @@
       Word key;
       Word val;
       struct _AvlNode* child[2]; /* [0] is left subtree, [1] is right */
-      Char balance;
+      Char balance; /* do not make this unsigned */
    }
    AvlNode;
 
@@ -496,13 +496,11 @@
    return nyu;
 }
 
-/* --- Public interface functions --- */
-
 /* Initialise a WordFM. */
-void TC_(initFM) ( WordFM* fm,
-                   void*   (*alloc_nofail)( SizeT ),
-                   void    (*dealloc)(void*),
-                   Word    (*kCmp)(Word,Word) )
+static void initFM ( WordFM* fm,
+                     void*   (*alloc_nofail)( SizeT ),
+                     void    (*dealloc)(void*),
+                     Word    (*kCmp)(Word,Word) )
 {
    fm->root         = 0;
    fm->kCmp         = kCmp;
@@ -511,6 +509,8 @@
    fm->stackTop     = 0;
 }
 
+/* --- Public interface functions --- */
+
 /* Allocate and Initialise a WordFM. */
 WordFM* TC_(newFM) ( void* (*alloc_nofail)( SizeT ),
                      void  (*dealloc)(void*),
@@ -518,7 +518,7 @@
 {
    WordFM* fm = alloc_nofail(sizeof(WordFM));
    tl_assert(fm);
-   TC_(initFM)(fm, alloc_nofail, dealloc, kCmp);
+   initFM(fm, alloc_nofail, dealloc, kCmp);
    return fm;
 }
 
@@ -685,6 +685,145 @@
 //---                       Implementation                       ---//
 //------------------------------------------------------------------//
 
+//------------------------------------------------------------------//
+//---                WordBag (unboxed words only)                ---//
+//---                       Implementation                       ---//
+//------------------------------------------------------------------//
+
+/* A trivial container, to make it opaque. */
+struct _WordBag { 
+   WordFM* fm; 
+};
+
+WordBag* TC_(newBag) ( void* (*alloc_nofail)( SizeT ),
+                       void  (*dealloc)(void*) )
+{
+   WordBag* bag = alloc_nofail(sizeof(WordBag));
+   bag->fm = TC_(newFM)( alloc_nofail, dealloc, NULL );
+   return bag;
+}
+
+void TC_(deleteBag) ( WordBag* bag )
+{
+   void (*dealloc)(void*) = bag->fm->dealloc;
+   TC_(deleteFM)( bag->fm, NULL, NULL );
+   VG_(memset)(bag, 0, sizeof(WordBag));
+   dealloc(bag);
+}
+
+void TC_(addToBag)( WordBag* bag, Word w )
+{
+   Word key, count;
+   if (TC_(lookupFM)(bag->fm, &key, &count, w)) {
+      tl_assert(key == w);
+      tl_assert(count >= 1);
+      TC_(addToFM)(bag->fm, w, count+1);
+   } else {
+      TC_(addToFM)(bag->fm, w, 1);
+   }
+}
+
+Word TC_(elemBag) ( WordBag* bag, Word w )
+{
+   Word key, count;
+   if (TC_(lookupFM)( bag->fm, &key, &count, w)) {
+      tl_assert(key == w);
+      tl_assert(count >= 1);
+      return count;
+   } else {
+      return 0;
+   }
+}
+
+Word TC_(sizeUniqueBag) ( WordBag* bag )
+{
+   return TC_(sizeFM)( bag->fm );
+}
+
+static Word sizeTotalBag_wrk ( AvlNode* nd )
+{
+   /* unchecked pre: nd is non-NULL */
+   Word w = nd->val;
+   tl_assert(w >= 1);
+   if (nd->child[0])
+      w += sizeTotalBag_wrk(nd->child[0]);
+   if (nd->child[1])
+      w += sizeTotalBag_wrk(nd->child[1]);
+   return w;
+}
+Word TC_(sizeTotalBag)( WordBag* bag )
+{
+   if (bag->fm->root)
+      return sizeTotalBag_wrk(bag->fm->root);
+   else
+      return 0;
+}
+
+Bool TC_(delFromBag)( WordBag* bag, Word w )
+{
+   Word key, count;
+   if (TC_(lookupFM)(bag->fm, &key, &count, w)) {
+      tl_assert(key == w);
+      tl_assert(count >= 1);
+      if (count > 1) {
+         TC_(addToFM)(bag->fm, w, count-1);
+      } else {
+         tl_assert(count == 1);
+         TC_(delFromFM)( bag->fm, NULL, w );
+      }
+      return True;
+   } else {
+      return False;
+   }
+}
+
+Bool TC_(isEmptyBag)( WordBag* bag )
+{
+   return TC_(sizeFM)(bag->fm) == 0;
+}
+
+Bool TC_(isSingletonTotalBag)( WordBag* bag )
+{
+   AvlNode* nd;
+   if (TC_(sizeFM)(bag->fm) != 1)
+      return False;
+   nd = bag->fm->root;
+   tl_assert(nd);
+   tl_assert(!nd->child[0]);
+   tl_assert(!nd->child[1]);
+   return nd->val == 1;
+}
+
+Word TC_(anyElementOfBag)( WordBag* bag )
+{
+   /* Return an arbitrarily chosen element in the bag.  We might as
+      well return the one at the root of the underlying AVL tree. */
+   AvlNode* nd = bag->fm->root;
+   tl_assert(nd); /* if this fails, 'bag' is empty - caller is in error. */
+   tl_assert(nd->val >= 1);
+   return nd->key;
+}
+
+void TC_(initIterBag)( WordBag* bag )
+{
+   TC_(initIterFM)(bag->fm);
+}
+
+Bool TC_(nextIterBag)( WordBag* bag, /*OUT*/Word* pVal, /*OUT*/Word* pCount )
+{
+   return TC_(nextIterFM)( bag->fm, pVal, pCount );
+}
+
+void TC_(doneIterBag)( WordBag* bag )
+{
+   TC_(doneIterFM)( bag->fm );
+}
+
+//------------------------------------------------------------------//
+//---             end WordBag (unboxed words only)               ---//
+//---                       Implementation                       ---//
+//------------------------------------------------------------------//
+
 /*--------------------------------------------------------------------*/
 /*--- end                                              tc_wordfm.c ---*/
 /*--------------------------------------------------------------------*/

Modified: branches/THRCHECK/thrcheck/tc_wordfm.h
===================================================================
--- branches/THRCHECK/thrcheck/tc_wordfm.h      2007-09-26 22:31:05 UTC (rev 
6913)
+++ branches/THRCHECK/thrcheck/tc_wordfm.h      2007-09-26 22:45:14 UTC (rev 
6914)
@@ -59,12 +59,6 @@
 
 typedef  struct _WordFM  WordFM; /* opaque */
 
-/* Initialise a WordFM */
-void TC_(initFM) ( WordFM* t, 
-                   void*   (*alloc_nofail)( SizeT ),
-                   void    (*dealloc)(void*),
-                   Word    (*kCmp)(Word,Word) );
-
 /* Allocate and initialise a WordFM */
 WordFM* TC_(newFM) ( void* (*alloc_nofail)( SizeT ),
                      void  (*dealloc)(void*),
@@ -86,6 +80,7 @@
 Bool TC_(lookupFM) ( WordFM* fm, 
                      /*OUT*/Word* keyP, /*OUT*/Word* valP, Word key );
 
+// How many elements are there in fm?
 Word TC_(sizeFM) ( WordFM* fm );
 
 // set up FM for iteration
@@ -113,6 +108,52 @@
 //---                      Public interface                      ---//
 //------------------------------------------------------------------//
 
+//------------------------------------------------------------------//
+//---                WordBag (unboxed words only)                ---//
+//---                      Public interface                      ---//
+//------------------------------------------------------------------//
+
+typedef  struct _WordBag  WordBag; /* opaque */
+
+/* Allocate and initialise a WordBag */
+WordBag* TC_(newBag) ( void* (*alloc_nofail)( SizeT ),
+                       void  (*dealloc)(void*) );
+
+/* Free up the Bag. */
+void TC_(deleteBag) ( WordBag* );
+
+/* Add a word. */
+void TC_(addToBag)( WordBag*, Word );
+
+/* Find out how many times the given word exists in the bag. */
+Word TC_(elemBag) ( WordBag*, Word );
+
+/* Delete a word from the bag. */
+Bool TC_(delFromBag)( WordBag*, Word );
+
+/* Is the bag empty? */
+Bool TC_(isEmptyBag)( WordBag* );
+
+/* Does the bag have exactly one element? */
+Bool TC_(isSingletonTotalBag)( WordBag* );
+
+/* Return an arbitrary element from the bag. */
+Word TC_(anyElementOfBag)( WordBag* );
+
+/* How many different / total elements are in the bag? */
+Word TC_(sizeUniqueBag)( WordBag* ); /* fast */
+Word TC_(sizeTotalBag)( WordBag* );  /* warning: slow */
+
+/* Iterating over the elements of a bag. */
+void TC_(initIterBag)( WordBag* );
+Bool TC_(nextIterBag)( WordBag*, /*OUT*/Word* pVal, /*OUT*/Word* pCount );
+void TC_(doneIterBag)( WordBag* );
+
+//------------------------------------------------------------------//
+//---             end WordBag (unboxed words only)               ---//
+//---                      Public interface                      ---//
+//------------------------------------------------------------------//
+
 #endif /* ! __TC_WORDFM_H */
 
 /*--------------------------------------------------------------------*/


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Valgrind-developers mailing list
Valgrind-developers@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/valgrind-developers

Reply via email to