# New Ticket Created by Josef Höök # Please include the string: [perl #16992] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=16992 >
I've noticed that the key patch defunced some function in multiarray ( somehow replaced key->next->next with key_next ). This patch fixes it. This patch also replaces [perl #16931]. /Josef -- attachment 1 ------------------------------------------------------ url: http://rt.perl.org/rt2/attach/36507/29473/0ea887/multiarray_020903.patch
--- multiarray.pmc.orig Sun Sep 1 20:32:13 2002 +++ multiarray.pmc Tue Sep 3 22:37:39 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: */ @@ -100,15 +100,16 @@ INTVAL loop_i; INTVAL inner_loop_i; dim_key = cell_data->dimension; - - my_key = key_next(interpreter, k); + my_key = k; if(cell_data->cell_buffer != NULL && dim_key != NULL && my_key != NULL ) { /* first part of alg. * (i + (j-1)*Ni */ - offset = key_integer(interpreter, k) + key_integer(interpreter, my_key) * key_integer(interpreter, dim_key); + offset = key_integer(interpreter, k); + k = key_next(interpreter, k); + offset += key_integer(interpreter, k) * key_integer(interpreter, dim_key); /* add the rest of algoritm * ... + (k-1)*Ni*Nj + (l-1)*Ni*Nj*Nk ... @@ -120,20 +121,19 @@ * */ loop_i = 2; - my_key = key_next(interpreter, my_key); - while ( my_key != NULL ) { - inner_loop_i = loop_i; - + + while ( key_next(interpreter, key_next(interpreter, my_key)) != NULL ) { + inner_loop_i = loop_i; while ( inner_loop_i > 0 && key_next(interpreter, dim_key) != NULL ) { 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; - + offset += key_integer(interpreter, key_next(interpreter, +key_next(interpreter, my_key))) * prod_of_dims; my_key = key_next(interpreter, my_key); loop_i++; } @@ -141,6 +141,7 @@ /* only 1 dim */ offset = key_integer(interpreter, k); } + return offset; } @@ -184,8 +185,6 @@ } - - static CELL_B *new_marray( Interp *interpreter ) { CELL_B *b = (CELL_B *)new_bufferlike_header(interpreter, sizeof(*b)); @@ -217,12 +216,11 @@ oldkey = key; size = 1; - - while (key_next(interpreter, key) != NULL) { - - size *= key_integer(interpreter, key); - key = key_next(interpreter, key); - + while (key != NULL) { + + size *= key_integer(interpreter, key); + key = key_next(interpreter, key); + } marray->size = size; @@ -230,7 +228,7 @@ 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 +243,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 +263,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 +318,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 +341,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); + + } 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) {