# New Ticket Created by Josef H��k
# Please include the string: [perl #16931]
# in the subject line of all future correspondence about this issue.
# <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=16931 >
Some minor updates on multiarray
/josef
-- attachment 1 ------------------------------------------------------
url: http://rt.perl.org/rt2/attach/36326/29355/79861a/multiarray_20020901.patch
--- multiarray.pmc.orig Sun Sep 1 20:32:13 2002
+++ multiarray.pmc Sun Sep 1 21:08:55 2002
@@ -10,7 +10,7 @@
* (y-1)X0+x
*
* Where X0 is the length of X-base (fig 1.1). We use this equation in
- * calc_offset to get offset from the buffer we store our data in.
+ * calc_offset_multi to get offset from the buffer we store our data in.
* Lets say we want to store (2,2) in a buffer. We then take values and do:
* (2-1)3 + 2 = 5.
*
@@ -36,12 +36,12 @@
* Current code has complexity:
*
* O(1) writing.
- * O(1) reading.
+ * O(?) reading.
* History:
- * Initial revision by Josef Hˆˆk
+ * Initial revision by Josef Hook <[EMAIL PROTECTED]>
* Notes:
- * Future plan is to make calc_offset_multi polymorphic
- * and to make it handle multidimensions: done
+ * Future plan is to handle multidimensions: done
+ * Move code into vtable functions:
* References:
*/
@@ -130,6 +130,7 @@
prod_of_dims *= key_integer(interpreter, dim_key);
dim_key = key_next(interpreter, dim_key);
inner_loop_i--;
+
}
offset += key_integer(interpreter, my_key) * prod_of_dims;
@@ -141,6 +142,7 @@
/* only 1 dim */
offset = key_integer(interpreter, k);
}
+
return offset;
}
@@ -217,20 +219,20 @@
oldkey = key;
size = 1;
-
while (key_next(interpreter, key) != NULL) {
-
- size *= key_integer(interpreter, key);
- key = key_next(interpreter, key);
-
+
+ size *= key_integer(interpreter, key);
+ key = key_next(interpreter, key);
+
}
+
marray->size = size;
marray->free_cell = size;
Parrot_reallocate(interpreter, marray->cell_buffer, marray->size * sizeof(CELL));
memset(marray->cell_buffer->bufstart, 0, marray->size * sizeof(CELL));
marray->dimension = oldkey;
-
+
}
@@ -245,6 +247,10 @@
INTVAL offs = 0;
INTVAL ret_val = 0;
+ INTVAL dead_val = 0;
+ INTVAL my_val = 0;
+ INTVAL iterate_count = 0;
+
offs = calc_offset_multi(interpreter, mg_marray, key);
base = (CELL *)mg_marray->cell_buffer->bufstart;
@@ -261,7 +267,48 @@
if(virtual_addr == buffer_ptr_virt) {
ret_val = buffer_ptr->data.int_val;
} else {
- /* PANIC */
+ /* OK here's the deal. We should never come to this point BUT if we have
+ * something must have happened to our cell buffer. Code below is
+ * a cut-paste from my matrix code though structures differs
+ * it should work anyway. TODO: verify its validity
+ */
+
+ dead_val = buffer_ptr->virtual_addr; // save our begin value
+ while(buffer_ptr->virtual_addr != offs && (buffer_ptr != NULL)) {
+
+ /* my_val = (offs - (buffer_ptr->sparse_offset)); */
+ my_val = (offs);
+ /* outside rand we dont have any value to collect */
+ if(my_val < 0) {
+ ret_val = 0;
+ break;
+ }
+ /* outside rand we dont have any value to collect */
+ if(my_val > buffer_ptr->virtual_addr) {
+ ret_val = 0;
+ break;
+ }
+ /* possible deadlock should never occur */
+ if(iterate_count > 100000) {
+ printf("AAYIE: possible deadlock in
+get_matrix_keyed(), recovering\n");
+ ret_val = 0;
+ break;
+ }
+ /* do some walking among our cells */
+ buffer_ptr = &base[my_val];
+ /*
+ * if true we have walked our way around
+ * which means no value to collect
+ */
+ if(buffer_ptr->virtual_addr == dead_val) {
+ ret_val = 0;
+ break;
+ }
+ ret_val = buffer_ptr->data.int_val;
+ iterate_count += 1;
+ }
+
+
}
}
@@ -275,7 +322,6 @@
CELL *my_cell;
CELL *base;
INTVAL offs = 0;
-
offs = calc_offset_multi(interpreter, sik_marray, key);
base = (CELL *)sik_marray->cell_buffer->bufstart;
my_cell = &base[offs];
@@ -299,14 +345,22 @@
SELF->flags |= (PMC_is_buffer_ptr_FLAG | PMC_is_PMC_ptr_FLAG);
SELF->data = NULL;
SELF->cache.int_val = 0;
- /* I use a PMC key class as wrapper to pass initialvalues to our multi array
- * OBS OBS OBS this dont work since we dont have a multidim key standard yet
- *if((initializer->vtable->type(INTERP, SELF)) == enum_class_Key) {
- * init_marray(INTERP, SELF, initializer->data);
- *} else{
- * init_marray(INTERP, SELF, NULL);
- *}
- */
+
+ if((initializer->vtable->type(INTERP, initializer)) == enum_class_Key){
+
+ init_marray(INTERP, SELF, initializer->data);
+
+ } else if ((initializer->vtable->type(INTERP, initializer)) ==
+ enum_class_PerlInt) {
+ /*
+ * we have probably been called from
+ * new(out PMC, in INT, in INT) do something usefull.
+ */
+
+ } else {
+ init_marray(INTERP, SELF, NULL); //no size
+ }
+
}
void morph (INTVAL type) {