[m-rev.] Version types for review
Julien Fischer
juliensf at cs.mu.OZ.AU
Fri Sep 3 18:25:55 AEST 2004
On Fri, 3 Sep 2004, Ralph Becket wrote:
> %-----------------------------------------------------------------------------%
> % version_store.m
> % Ralph Becket <rafe at cs.mu.oz.au>
> % Thu Jan 22 12:01:19 EST 2004
> % vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
> %
> % (See the header comments in version_types.m for an explanation of version
> % types.)
> %
> % A version store - this operates with similar efficiency to an ordinary
> % store, but "older" versions of the store are still available, but work
> % less efficiently as more updates are made to the "latest" version of
> % the store. Operations on the "latest" version are always O(1).
That paragraph could be expressed better.
> %
> % The advantage of version stores is that they are ordinary ground terms
> % and can therefore be nested and so forth without the need for complicated
> % insts.
> %
> %-----------------------------------------------------------------------------%
This is one of the benefits of version structures in general. I think
you should probably mention that in version_types.m as well.
>
> :- module version_store.
>
> :- interface.
>
>
>
> :- type version_store(S).
>
> :- type mutvar(T, S).
>
>
>
> % Construct a new version store. This is distinguised from other
s/distinguised/distinguished/
> % version stores by its existentially quantified type. This means
> % the compiler can automatically detect any attempt to use a
> % mutvar with the wrong version store.
> %
> :- some [S] func new = version_store(S).
>
...
> % set(VS, Mutvar, X) = ( VS ^ elem(Mutvar) := X ).
> %
> :- func set(version_store(S), mutvar(T, S), T) = version_store(S).
>
> % A version of the above suitable for use with state variables.
> %
> :- pred set_mutvar(mutvar(T, S)::in, T::in,
> version_store(S)::in, version_store(S)::out) is det.
I don't think you need to keep saying that the predicate
versions are suitable for use with state variables. State
variables work with both versions - the predicate version
is just a little more convenient. Our current coding
standard suggest placing the declarations for both
the predicate and function versions of the same operation
under a common comment.
>
> % unsafe_rewind(VS) produces a version of VS for which all accesses are
> % O(1). Invoking this predicate renders VS and all later versions
> % undefined that were derived by performing individual updates.
That should probably say:
Invoking this predicate renders VS and all later vsions that
were derived by performing individual updates undefined.
> Only use
> % this when you are absolutely certain there are no live references to VS
> % or later versions of VS.
> %
> :- func unsafe_rewind(version_store(T)) = version_store(T).
>
> % VS version of the above suitable for use with state variables.
> %
> :- pred unsafe_rewind(version_store(T)::in, version_store(T)::out) is det.
>
...
>
> %-----------------------------------------------------------------------------%
> % Copyright (C) 2001-2002 The University of Melbourne
> % This file may only be copied under the terms of the GNU Library General
> % Public License - see the file COPYING.LIB in the Mercury distribution.
> % vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
> %-----------------------------------------------------------------------------%
2002? Surely you've worked on it since then.
> % version_bitmap.m
> % Ralph Becket <rafe at cs.mu.oz.au>
> %
> % (See the header comments in version_types.m for an explanation of version
> % types.)
> %
> % Version bitmaps: an implementation of bitmaps using version arrays.
> %
> % The advantage of version bitmaps is that in the common, singly threaded,
> % case, they are almost as fast as unique bitmaps, but can be treated as
> % ordinary ground values rather than unique values.
> %
> %-----------------------------------------------------------------------------%
>
> :- module version_bitmap.
>
> :- interface.
>
> :- import_module int, bool.
>
>
>
> :- type version_bitmap.
>
> % new(N, B) creates a version_bitmap of size N (indexed 0 .. N-1)
> % setting each bit if B = yes and clearing each bit if B = no.
> % An exception is thrown if N is negative.
> %
> :- func new(int, bool) = version_bitmap.
>
> % Returns the number of bits in a version_bitmap.
> %
> :- func num_bits(version_bitmap) = int.
>
> % set(BM, I), clear(BM, I) and flip(BM, I) set, clear and flip
> % bit I in BM respectively. An exception is thrown if I is out
> % of range.
> %
> :- func set(version_bitmap, int) = version_bitmap.
>
> :- func clear(version_bitmap, int) = version_bitmap.
>
> :- func flip(version_bitmap, int) = version_bitmap.
>
> % Versions of the above suitable for use with state variables.
> %
> :- pred set(int::in, version_bitmap::in, version_bitmap::out) is det.
>
> :- pred clear(int::in, version_bitmap::in, version_bitmap::out) is det.
>
> :- pred flip(int::in, version_bitmap::in, version_bitmap::out) is det.
>
As mentioned above it's probably better that the declarations for
the predicate versions are grouped together with the function versions.
> % is_set(BM, I) and is_clear(BM, I) succeed iff bit I in BM
> % is set or clear respectively.
> %
> :- pred is_set(version_bitmap, int).
> :- mode is_set(in, in) is semidet.
>
> :- pred is_clear(version_bitmap, int).
> :- mode is_clear(in, in) is semidet.
>
Is there any reason you haven't used predmode syntax here?
...
> %-----------------------------------------------------------------------------%
>
> :- pred in_range(version_bitmap, int).
> :- mode in_range(in, in) is semidet.
>
Again, you should probably use predmode syntax here.
> %-----------------------------------------------------------------------------%
> % Copyright (C) 2001, 2003 The University of Melbourne
> % This file may only be copied under the terms of the GNU Library General
> % Public License - see the file COPYING.LIB in the Mercury distribution.
> % vim: ft=mercury ts=4 sw=4 et tw=0 wm=0
> %-----------------------------------------------------------------------------%
> %
> % File: version_hash_table.m
> % Main author: rafe
> % Stability: low
> %
...
> :- func search(version_hash_table(K, V), K) = V is semidet.
> :- pred search(version_hash_table(K, V)::in, K::in, V::out) is semidet.
>
> % Convert a hash table into an association list.
> %
> :- func to_assoc_list(version_hash_table(K, V)) = assoc_list(K, V).
>
It might also be worth providing a from_assoc_list function.
> % Fold a function over the key-value bindings in a hash table.
> %
> :- func fold(func(K, V, T) = T, version_hash_table(K, V), T) = T.
>
> %-----------------------------------------------------------------------------%
> %-----------------------------------------------------------------------------%
> :- implementation.
>
...
> %-----------------------------------------------------------------------------%
>
> set(HT0, K, V) = HT :-
>
> % If this is the first entry in the hash table, then we use it to
> % set up the hash table (the version_arrays are currently empty because
> % we need values to initialise them with).
> %
Fix the indentation there (assuming that it's not cvs or my mail reader
doing that).
More later.
Julien.
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list