# New Ticket Created by  Dino Morelli 
# Please include the string:  [perl #36244]
# in the subject line of all future correspondence about this issue. 
# <URL: https://rt.perl.org/rt3/Ticket/Display.html?id=36244 >


As per discussions with Leo and Jerry, new allocation code for
resizablebooleanarray to support...

adding push_integer, pop_integer, shift_integer, unshift_integer

Some other things like freeze/thaw added as well because of this.


Removed push_integer from fixedbooleanarray


Files:

classes/fixedbooleanarray.pmc
classes/resizablebooleanarray.pmc
t/pmc/resizablebooleanarray.t


-- 
 .~.    Dino Morelli
 /V\    email: [EMAIL PROTECTED]
/( )\   weblog: http://categorically.net/d/blog/
^^-^^   preferred distro: Debian GNU/Linux  http://www.debian.org
Index: classes/fixedbooleanarray.pmc

===================================================================

--- classes/fixedbooleanarray.pmc       (revision 8300)

+++ classes/fixedbooleanarray.pmc       (working copy)

@@ -458,22 +458,6 @@

 

 /*

 

-=item C<void push_integer (INTVAL value)>

-

-Extends the array by adding an element of value C<value> to the end of

-the array.

-

-=cut

-

-*/

-

-    void push_integer (INTVAL value) {

-        INTVAL nextix = DYNSELF.elements();

-        DYNSELF.set_integer_keyed_int(nextix, value);

-    }

-

-/*

-

 =back

 

 =head2 Freeze/thaw Interface

@@ -530,6 +514,8 @@

 

 Initial version 2004.06.11 by Matt Fowles

 

+Removed push_integer             - Dino Morelli 2004-06-10

+

 =cut

 

 */

Index: classes/resizablebooleanarray.pmc

===================================================================

--- classes/resizablebooleanarray.pmc   (revision 8300)

+++ classes/resizablebooleanarray.pmc   (working copy)

@@ -25,6 +25,7 @@

 

 

 #define BITS_PER_CHAR 8

+#define MIN_ALLOC 8 * BITS_PER_CHAR

 

 pmclass ResizableBooleanArray extends FixedBooleanArray need_ext does array {

 

@@ -49,10 +50,13 @@

 */

 

     INTVAL get_integer_keyed_int (INTVAL key) {

-        Parrot_UInt1 *sd;

         if (key < 0)

             internal_exception(OUT_OF_BOUNDS,

                 "ResizableBooleanArray: index out of bounds!");

+

+        /* Adjust key for the current head position */

+        key += PMC_int_val2(SELF);

+

         if(key >= PMC_int_val(SELF))

             DYNSELF.set_integer_native(key+1);

 

@@ -70,6 +74,9 @@

 */

 

     void set_integer_keyed_int (INTVAL key, INTVAL value) {

+        /* Adjust key for the current head position */

+        key += PMC_int_val2(SELF);

+

         if (key < 0)

             internal_exception(OUT_OF_BOUNDS,

                 "ResizableBooleanArray: index out of bounds!");

@@ -91,30 +98,223 @@

 

     void set_integer_native (INTVAL size) {

         Parrot_UInt1 *sd;

+        INTVAL newASize;

+        INTVAL currSize = PMC_int_val(SELF) - PMC_int_val2(SELF);

+

+        /* We are already at the requested size. Yay */

+        if(size == currSize) return;

+

         if (size < 0)

             internal_exception(OUT_OF_BOUNDS,

-                    "ResizableBooleanArray: Can't resize!");

+                "ResizableBooleanArray: Can't resize!");

 

+        newASize = (size / MIN_ALLOC + 1) * MIN_ALLOC;

+

+        /* Nothing allocated yet */

         if ( ! PMC_data(SELF) ) {

-            SUPER(size);

-        } else if ( size > PMC_int_val2(SELF) ) {

-            INTVAL old_size = PMC_int_val2(SELF);

-            PMC_int_val2(SELF) = size < 2*old_size ? 2*old_size : 
(size/BITS_PER_CHAR+1)*BITS_PER_CHAR;

+            PMC_data(SELF) = mem_sys_allocate_zeroed(newASize);

+        }

+        else {

             sd = PMC_data(SELF);

-            PMC_data(SELF) = mem_sys_realloc(sd, 
PMC_int_val2(SELF)/BITS_PER_CHAR);

-            PMC_int_val(SELF) = size;

-        } else {

-            PMC_int_val(SELF) = size;

-            return;

+            PMC_data(SELF) = mem_sys_realloc(sd, newASize);

         }

+

+        PMC_int_val2(SELF) = 0;

+        PMC_int_val(SELF) = size;

     }

 

-}

+/*

 

+=item C<void push_integer(INTVAL size)>

+

+Extends the array by adding an element of value C<value> to the end.

+

+=cut

+

+*/

+

+    void push_integer (INTVAL value) {

+        INTVAL size = PMC_int_val(SELF) - PMC_int_val2(SELF);

+        DYNSELF.set_integer_native(size + 1);

+        DYNSELF.set_integer_keyed_int(size, value);

+    }

+

 /*

 

+=item C<void pop_integer(INTVAL size)>

+

+Removes and returns the last element.

+

+=cut

+

+*/

+

+    INTVAL pop_integer () {

+        INTVAL size = PMC_int_val(SELF) - PMC_int_val2(SELF);

+        INTVAL value = DYNSELF.get_integer_keyed_int(size - 1);

+        DYNSELF.set_integer_native(size - 1);

+

+        return value;

+    }

+

+/*

+

+=item C<void unshift_integer(INTVAL size)>

+

+Extends the array by adding an element of value C<value> to the 

+beginning.

+

+=cut

+

+*/

+

+    void unshift_integer (INTVAL value) {

+        Parrot_UInt1 *sdOld, *sdNew;

+

+        /* If int_val2 is smaller than 0, size this thing up */

+        if(PMC_int_val2(SELF) <= 0) {

+            sdOld = PMC_data(SELF);

+            sdNew = mem_sys_allocate_zeroed(

+                ((PMC_int_val2(SELF) / MIN_ALLOC) * MIN_ALLOC) 

+                + PMC_int_val(SELF)

+                + ((PMC_int_val(SELF) / MIN_ALLOC + 1) * MIN_ALLOC)

+            );

+            mem_sys_memmove(sdNew, sdOld + PMC_int_val2(SELF), 

+                PMC_int_val(SELF));

+            mem_sys_free(sdOld);

+            PMC_data(SELF) = sdNew;

+            PMC_int_val2(SELF) += MIN_ALLOC;

+            PMC_int_val(SELF) += MIN_ALLOC;

+        }

+

+        /* Move the head position */

+        PMC_int_val2(SELF)--;

+

+        /* Assign the new value as the first item */

+        DYNSELF.set_integer_keyed_int(0, value);

+    }

+

+/*

+

+=item C<void shift_integer(INTVAL size)>

+

+Removes and returns the first element.

+

+=cut

+

+*/

+

+    INTVAL shift_integer () {

+        INTVAL value;

+        Parrot_UInt1 *sdOld, *sdNew;

+        

+

+        if (DYNSELF.elements() < 1)

+            internal_exception(OUT_OF_BOUNDS,

+                "ResizableBooleanArray: Can't shift from an empty array!");

+

+        /* Get head value */

+        value = DYNSELF.get_integer_keyed_int(0);

+

+        /* Move the head position */

+        PMC_int_val2(SELF)++;

+

+        /* If int_val2 is bigger than our allocation unit size, size

+            this thing down */

+        if(PMC_int_val2(SELF) >= MIN_ALLOC) {

+            sdOld = PMC_data(SELF);

+            sdNew = mem_sys_allocate_zeroed(

+                ((PMC_int_val2(SELF) / MIN_ALLOC) * MIN_ALLOC) 

+                + PMC_int_val(SELF)

+                + ((PMC_int_val(SELF) / MIN_ALLOC + 1) * MIN_ALLOC)

+            );

+            mem_sys_memmove(sdNew, sdOld + PMC_int_val2(SELF), 

+                PMC_int_val(SELF));

+            mem_sys_free(sdOld);

+            PMC_data(SELF) = sdNew;

+        }

+

+        return value;

+    }

+

+/*

+

+=item C<INTVAL elements()>

+

+=cut

+

+*/

+

+    INTVAL elements () {

+        return PMC_int_val(SELF) - PMC_int_val2(SELF);

+    }

+

+/*

+

+=item C<INTVAL get_integer()>

+

+Returns the number of elements in the array.

+

+=cut

+

+*/

+

+    INTVAL get_integer () {

+        return SELF.elements();

+    }

+

+/*

+

 =back

 

+=head2 Freeze/thaw Interface

+

+=over 4

+

+=item C<void freeze(visit_info *info)>

+

+Used to archive the string.

+

+=cut

+

+*/

+    void freeze(visit_info *info) {

+        IMAGE_IO *io = info->image_io;

+        STRING *s;

+        INTVAL headPos = PMC_int_val2(SELF);

+        INTVAL size = PMC_int_val(SELF) - headPos;

+

+        io->vtable->push_integer(INTERP, io, size);

+        s = string_from_cstring(INTERP, PMC_data(SELF) + headPos, 

+            size / MIN_ALLOC);

+        io->vtable->push_string(INTERP, io, s);

+    }

+

+/*

+

+=item C<void thaw(visit_info *info)>

+

+Used to unarchive the string.

+

+=cut

+

+*/

+    void thaw(visit_info *info) {

+        IMAGE_IO *io = info->image_io;

+        INTVAL size = io->vtable->shift_integer(INTERP, io);

+        STRING *s = io->vtable->shift_string(INTERP, io);

+

+        DYNSELF.set_integer_native(size);

+        mem_sys_memcopy(PMC_data(SELF) + PMC_int_val2(SELF),

+            s->strstart, s->bufused);

+    }

+

+}  /* pmclass */

+

+/*

+

+=back

+

 =head1 SEE ALSO

 

 F<docs/pdds/pdd17_basic_types.pod>.

@@ -122,9 +322,15 @@

 =head1 HISTORY

 

 Initial version                  - Matt Fowles 2004-06-11

+

 Changed allocator to double size - Matt Fowles 2004-06-15

+

 Added push_integer               - Bernhard Schmalhofer 2004-10-17

 

+Changed allocation code, added   - Dino Morelli 2005-06-10

+  push_, pop_, shift_, 

+  unshift_integer, freeze, thaw

+

 =cut

 

 */

Index: t/pmc/resizablebooleanarray.t

===================================================================

--- t/pmc/resizablebooleanarray.t       (revision 8300)

+++ t/pmc/resizablebooleanarray.t       (working copy)

@@ -16,9 +16,12 @@

 

 =cut

 

-use Parrot::Test tests => 9;

+use strict;

+use warnings;

+use Parrot::Test tests => 11;

 use Test::More;

 

+

 my $fp_equality_macro = <<'ENDOFMACRO';

 .macro fp_eq ( J, K, L )

        save    N0

@@ -62,6 +65,7 @@

 .endm

 ENDOFMACRO

 

+

 pasm_output_is(<<'CODE', <<'OUTPUT', "Setting array size");

        new P0, .ResizableBooleanArray

 

@@ -102,6 +106,7 @@

 ok 5

 OUTPUT

 

+

 pasm_output_is(<<'CODE', <<'OUTPUT', "Setting first element");

         new P0, .ResizableBooleanArray

         set P0, 1

@@ -160,6 +165,7 @@

 ok 3

 OUTPUT

 

+

 # TODO: Rewrite these properly when we have exceptions

 

 pasm_output_is(<<'CODE', <<'OUTPUT', "Setting out-of-bounds elements");

@@ -190,6 +196,7 @@

 ok 3

 OUTPUT

 

+

 pasm_output_is(<<'CODE', <<'OUTPUT', "Getting out-of-bounds elements");

         new P0, .ResizableBooleanArray

         set P0, 1

@@ -238,6 +245,7 @@

 ok 3

 OUTPUT

 

+

 pasm_output_is(<<"CODE", <<'OUTPUT', "Set via INTs, access via PMC Keys");

 @{[ $fp_equality_macro ]}

      new P0, .ResizableBooleanArray

@@ -284,6 +292,7 @@

 ok 4

 OUTPUT

 

+

 pir_output_is(<< 'CODE', << 'OUTPUT', "check whether interface is done");

 

 .sub _main

@@ -307,6 +316,7 @@

 0

 OUTPUT

 

+

 pir_output_is(<< 'CODE', << 'OUTPUT', "push integer");

 

 .sub _main

@@ -328,3 +338,149 @@

 10001

 1

 OUTPUT

+

+

+pir_output_is(<< 'CODE', << 'OUTPUT', "push and pop");

+

+.sub test @MAIN

+       .local int i, i_elem

+       .local pmc pmc_arr

+       .local int elements

+

+       i= 1

+       pmc_arr= new ResizableBooleanArray

+

+       print_num_elements( pmc_arr )

+       

+       push pmc_arr, i

+       print i

+       print_num_elements( pmc_arr )

+

+       push pmc_arr, 0

+       print 0

+       print_num_elements( pmc_arr )

+

+       print_num_elements( pmc_arr )

+

+       i_elem= pop pmc_arr

+       print i_elem

+       print_num_elements( pmc_arr )

+

+       i_elem= pop pmc_arr

+       print i_elem

+       print_num_elements( pmc_arr )

+

+    pmc_arr = 62

+    push pmc_arr, 0

+    push pmc_arr, 1

+    push pmc_arr, 0

+    push pmc_arr, 1

+    i_elem = pop pmc_arr

+    i_elem = pop pmc_arr

+    i_elem = pop pmc_arr

+    print i_elem

+    print_num_elements(pmc_arr)

+

+    pmc_arr = 0

+       i_elem= pop pmc_arr

+       print i_elem

+       print_num_elements( pmc_arr )

+

+.end

+

+.sub print_num_elements

+       .param pmc pmc_arr

+       .local int elements

+       elements= pmc_arr

+       print '['

+       print elements

+       print "]\n"

+       .return()

+.end

+

+CODE

+[0]

+1[1]

+0[2]

+[2]

+0[1]

+1[0]

+1[63]

+ResizableBooleanArray: index out of bounds!

+OUTPUT

+

+

+pir_output_is(<< 'CODE', << 'OUTPUT', "unshift and shift");

+

+.sub test @MAIN

+       .local int i, i_elem

+       .local pmc pmc_arr

+       .local int elements

+

+       i= 1

+       pmc_arr= new ResizableBooleanArray

+

+       print_num_elements( pmc_arr )

+       

+       unshift pmc_arr, i

+       print i

+       print_num_elements( pmc_arr )

+

+       unshift pmc_arr, 0

+       print 0

+       print_num_elements( pmc_arr )

+

+       print_num_elements( pmc_arr )

+

+       i_elem= shift pmc_arr

+       print i_elem

+       print_num_elements( pmc_arr )

+

+       i_elem= shift pmc_arr

+       print i_elem

+       print_num_elements( pmc_arr )

+

+    pmc_arr = 62

+    unshift pmc_arr, 0

+    unshift pmc_arr, 1

+    unshift pmc_arr, 0

+    unshift pmc_arr, 1

+    i_elem = shift pmc_arr

+    i_elem = shift pmc_arr

+    i_elem = shift pmc_arr

+    print i_elem

+    print_num_elements(pmc_arr)

+

+    # Set same size array is currently

+    pmc_arr = 63

+    print_num_elements(pmc_arr)

+

+    pmc_arr = 0

+       i_elem= shift pmc_arr

+       print i_elem

+       print_num_elements( pmc_arr )

+

+    end

+.end

+

+.sub print_num_elements

+       .param pmc pmc_arr

+       .local int elements

+       elements= pmc_arr

+       print '['

+       print elements

+       print "]\n"

+       .return()

+.end

+

+CODE

+[0]

+1[1]

+0[2]

+[2]

+0[1]

+1[0]

+1[63]

+[63]

+ResizableBooleanArray: Can't shift from an empty array!

+OUTPUT

Reply via email to