[m-rev.] for review: avoid memory allocation in version_hash_table

Peter Wang novalazy at gmail.com
Fri Jun 27 12:15:19 AEST 2008


Estimated hours taken: 0.1
Branches: main

library/version_hash_table.m:
	Don't wrap the user-supplied hash predicate (with two outputs) by a
	hash function (that returns a tuple of two values) to avoid an inst
	cast.  Each lookup incurs an additional memory allocation to create
	the tuple.

Index: library/version_hash_table.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/version_hash_table.m,v
retrieving revision 1.8
diff -u -p -r1.8 version_hash_table.m
--- library/version_hash_table.m	27 Sep 2006 06:16:45 -0000	1.8
+++ library/version_hash_table.m	27 Jun 2008 02:00:55 -0000
@@ -167,12 +167,10 @@
                 num_buckets             :: int,
                 num_occupants           :: int,
                 max_occupants           :: int,
-                hash_func               :: hash_func(K),
+                hash_pred               :: hash_pred(K),
                 buckets                 :: buckets(K, V)
             ).
 
-:- type hash_func(K) == (func(K) = {int, int}).
-
 :- type buckets(K, V) == version_array(bucket(K, V)).
 
 :- type bucket(K, V)
@@ -209,9 +207,8 @@ new(HashPred, N, MaxOccupancy) = HT :-
       else
             NumBuckets   = 1 << N,
             MaxOccupants = ceiling_to_int(float(NumBuckets) * MaxOccupancy),
-            HashFunc     = (func(X) = {I, J} :- HashPred(X, I, J)),
             VArray       = version_array.init(NumBuckets, empty),
-            HT = ht(NumBuckets, 0, MaxOccupants, HashFunc, VArray)
+            HT = ht(NumBuckets, 0, MaxOccupants, HashPred, VArray)
     ).
 
 %-----------------------------------------------------------------------------%
@@ -235,7 +232,8 @@ new_default(HashPred) = new(HashPred, 7,
 :- func find_slot(version_hash_table(K, V), K) = int.
 
 find_slot(HT, K) = H :-
-    {Hash1, Hash2} = (HT ^ hash_func)(K),
+    unsafe_hash_pred_cast(HT ^ hash_pred, HashPred),
+    HashPred(K, Hash1, Hash2),
     H0    = Hash1 mod HT ^ num_buckets,
             % Have to ensure it's odd and non-zero.
     Delta = Hash2 + Hash2 + 1,
@@ -258,6 +256,16 @@ find_slot_2(HT, K, H0, Delta) = H :-
         )
     ).
 
+:- pred unsafe_hash_pred_cast(hash_pred(K)::in, hash_pred(K)::out(hash_pred))
+    is det.
+
+:- pragma foreign_proc("C",
+    unsafe_hash_pred_cast(HashPred0::in, HashPred::out(hash_pred)),
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    HashPred = HashPred0;
+").
+
 %-----------------------------------------------------------------------------%
 
 set(HT0, K, V) = HT :-


--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list