[m-rev.] for review: improvements to bitmap.m [1]

Ralph Becket rafe at csse.unimelb.edu.au
Mon Feb 12 12:55:19 AEDT 2007


Simon Taylor, Sunday, 11 February 2007:
> For review by Ralph.
> 
> 
> Estimated hours taken: 80
> Branches: main
> 
> Improvements for bitmap.m, to make it more useable as a general container
> for binary data.

Thanks for doing this.  I can't see any problems in the code.
One thing: there have been several requests over the years for a byte
array data type.  Would a bitmap be a suitable implementation for a
byte array or vice versa?

> Index: library/bitmap.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/library/bitmap.m,v
> retrieving revision 1.14
> diff -u -u -r1.14 bitmap.m
> +%-----------------------------------------------------------------------------%
>  
> -resize(BM0, N, B) = BM :-
> -    ( if N =< 0 then
> -        BM      = new(N, B)
> +resize(!.BM, NewSize, InitializerBit) = !:BM :-
> +    ( if NewSize =< 0 then
> +        !:BM = new(NewSize, InitializerBit)
>        else
> -        X       = initializer(B),
> -        NumInts = num_ints_required(N),
> -        BM1     = array.resize(BM0, NumInts, X),
> -
> -            % Now we need to ensure that bits N, N+1, N+2, ... up to
> -            % the word boundary are initialized properly.
> -            %
> -        int.min(num_bits(BM0), N, M),
> -        Offset  = int_offset(M - 1),
> -        Mask    = bitsmask(M - 1),          % For bits we need to preserve.
> -        Bits    = \(Mask) /\ X,             % Bits we need to fill in.
> -        BM2     = (( BM1
> -                        ^ elem(0)      := N )
> -                        ^ elem(Offset) := (BM1 ^ elem(Offset) /\ Mask) \/ Bits),
> -        BM      = clear_filler_bits(BM2)
> +        OldSize = num_bits(!.BM),
> +        InitializerByte = initializer(InitializerBit),
> +        !:BM = resize_bitmap(!.BM, NewSize),
> +        ( if NewSize > OldSize then
> +            % Fill in the trailing bits in the previous final byte.
> +            !:BM = set_trailing_bits_in_byte(!.BM, OldSize - 1,
> +                        InitializerByte),
> +            OldLastByte = byte_index_for_bit(OldSize - 1),
> +            NewLastByte = byte_index_for_bit(NewSize - 1),

I would have used an name like OldLastByteIdx or something like that.
OldLastByte sounds like it refers to a byte rather than a byte index.

> +
> +    % Extract the given number of bits starting at the most significant.
> +:- pred extract_bits_from_bytes(byte_index, bit_index_in_byte, num_bits,
> +    bitmap, word, word).
> +%:- mode extract_bits_from_bytes(in, in, in, bitmap_ui, in, out) is det.
> +:- mode extract_bits_from_bytes(in, in, in, in, in, out) is det.
> +
> +extract_bits_from_bytes(FirstByte, FirstBitIndex, NumBits, BM, !Bits) :-
> +    RemainingBitsInByte = bits_per_byte - FirstBitIndex,
> +    ( NumBits > RemainingBitsInByte ->
> +        NumBitsThisByte = RemainingBitsInByte,
> +        extract_bits_from_byte_index(FirstByte, FirstBitIndex,
> +            NumBitsThisByte, BM, !Bits),
> +        extract_bits_from_bytes(FirstByte + 1, 0,
> +            NumBits - NumBitsThisByte, BM, !Bits)
> +    ; NumBits > 0 ->
> +        extract_bits_from_byte_index(FirstByte, FirstBitIndex,
> +            NumBits, BM, !Bits)
> +    ;
> +        true
> +    ).

The convention in the original bitmap.m was to use if-then-else rather
than ( -> ; ).  It's a good idea to just use one style in the same
module.

-- Ralph
--------------------------------------------------------------------------
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