Annotation of parser3/src/main/pa_array.C, revision 1.19

1.1       paf         1: /*
1.19    ! paf         2:   $Id: pa_array.C,v 1.18 2001/02/22 15:17:40 paf Exp $
1.1       paf         3: */
                      4: 
                      5: #include <string.h>
                      6: 
                      7: #include "pa_pool.h"
1.8       paf         8: #include "pa_array.h"
1.13      paf         9: #include "pa_exception.h"
1.1       paf        10: 
1.10      paf        11: Array::Array(Pool& apool, int initial_rows) :
1.13      paf        12:        Pooled(apool) {
1.6       paf        13:        head=tail=static_cast<Chunk *>(
1.17      paf        14:                malloc(sizeof(int)+sizeof(Chunk::Row)*initial_rows+sizeof(Chunk *)));
1.6       paf        15:        head->count=initial_rows;
1.1       paf        16:        append_here=head->rows;
1.6       paf        17:        link_row=&head->rows[initial_rows];
1.1       paf        18:        link_row->link=0;
                     19:        fused_rows=0;
1.2       paf        20: 
1.3       paf        21:        cache_chunk_base=0;
                     22:        cache_chunk=head;
1.1       paf        23: }
                     24: 
1.9       paf        25: void Array::expand(int chunk_rows) {
1.6       paf        26:        Chunk *chunk=tail=static_cast<Chunk *>(
1.17      paf        27:                malloc(sizeof(int)+sizeof(Chunk::Row)*chunk_rows+sizeof(Chunk *)));
1.6       paf        28:        chunk->count=chunk_rows;
1.1       paf        29:        link_row->link=chunk;
                     30:        append_here=chunk->rows;
1.6       paf        31:        link_row=&chunk->rows[chunk_rows];
1.1       paf        32:        link_row->link=0;
                     33: }
                     34: 
                     35: 
1.15      paf        36: Array& Array::operator += (Item *src) {
1.1       paf        37:        if(chunk_is_full())
1.6       paf        38:                expand(tail->count*CR_GROW_PERCENT/100);
1.1       paf        39: 
                     40:        append_here->item=src;
                     41:        append_here++; fused_rows++;
                     42: 
                     43:        return *this;
                     44: }
                     45: 
1.15      paf        46: Array::Item *Array::get(int index) const {
1.3       paf        47:        if(!(index>=0 && index<size())) {
1.17      paf        48:                THROW(0, 0, 0, 
1.12      paf        49:                        "Array::get(%d) out of range [0..%d]", index, size()-1);
1.10      paf        50:                return 0;
1.2       paf        51:        }
                     52: 
1.3       paf        53:        // if they ask index to the left of cached position, forget cache
                     54:        if(index<cache_chunk_base) {
                     55:                cache_chunk_base=0;
                     56:                cache_chunk=head;
                     57:        }
                     58: 
                     59:        // navigate to chunk with "index" row
                     60:        while(!(index>=cache_chunk_base && index<cache_chunk_base+cache_chunk->count)) {
                     61:                int count=cache_chunk->count;
                     62:                cache_chunk_base+=count;
                     63:                cache_chunk=cache_chunk->rows[count].link;
                     64:        }
                     65: 
                     66:        return cache_chunk->rows[index-cache_chunk_base].item;
1.16      paf        67: }
                     68: 
                     69: void Array::put(int index, Item *item) {
                     70:        if(!(index>=0 && index<size())) {
1.17      paf        71:                THROW(0, 0, 0, 
1.16      paf        72:                        "Array::put(%d) out of range [0..%d]", index, size()-1);
                     73:                return;
                     74:        }
                     75: 
                     76:        // if they ask index to the left of cached position, forget cache
                     77:        if(index<cache_chunk_base) {
                     78:                cache_chunk_base=0;
                     79:                cache_chunk=head;
                     80:        }
                     81: 
                     82:        // navigate to chunk with "index" row
                     83:        while(!(index>=cache_chunk_base && index<cache_chunk_base+cache_chunk->count)) {
                     84:                int count=cache_chunk->count;
                     85:                cache_chunk_base+=count;
                     86:                cache_chunk=cache_chunk->rows[count].link;
                     87:        }
                     88: 
                     89:        cache_chunk->rows[index-cache_chunk_base].item=item;
1.4       paf        90: }
                     91: 
1.18      paf        92: Array& Array::append_array(const Array& src, int offset) {
                     93:        int src_rows_to_copy=src.fused_rows-offset;
1.4       paf        94:        int last_chunk_rows_left=link_row-append_here;
                     95:        
1.5       paf        96:        // our last chunk too small for src to fit?
1.18      paf        97:        if(src_rows_to_copy>last_chunk_rows_left) {
1.5       paf        98:                // shrink last chunk to used rows
                     99:                tail->count-=last_chunk_rows_left;
                    100:                link_row=append_here;
                    101: 
1.6       paf       102:                // append new src_used_rows-ed chunk 
1.18      paf       103:                expand(src_rows_to_copy);
1.5       paf       104:        }
                    105: 
1.18      paf       106:        Chunk *src_chunk=src.head;
1.6       paf       107:        Chunk::Row *dest_rows=append_here;
1.18      paf       108:        int rows_left_to_copy=src.fused_rows;
                    109:        int rows_left_to_skip=offset;
1.6       paf       110:        while(true) {
                    111:                int src_count=src_chunk->count;
                    112:                Chunk *next_chunk=src_chunk->rows[src_count].link;
                    113:                if(next_chunk) {
                    114:                        // not last source chunk
                    115:                        // taking it all
1.18      paf       116:                        int rows_to_copy_now=src_count-rows_left_to_skip;
                    117:                        if(rows_to_copy_now>0)
                    118:                                memcpy(dest_rows, src_chunk->rows+rows_left_to_skip, 
                    119:                                        sizeof(Chunk::Row)*rows_to_copy_now);
1.19    ! paf       120:                        else
        !           121:                                rows_left_to_skip-=src_count;
        !           122: 
1.18      paf       123:                        dest_rows+=rows_to_copy_now;
1.6       paf       124:                        rows_left_to_copy-=src_count;
                    125:                        src_chunk=next_chunk;
                    126:                } else {
                    127:                        // the last source chunk
                    128:                        // taking only those rows of chunk that _left_to_copy
1.18      paf       129:                        int rows_to_copy_now=rows_left_to_copy-rows_left_to_skip;
                    130:                        if(rows_to_copy_now>0)
                    131:                                memcpy(dest_rows, src_chunk->rows+rows_left_to_skip, 
                    132:                                        sizeof(Chunk::Row)*rows_to_copy_now);
1.6       paf       133:                        break;
1.4       paf       134:                }
                    135:        }
1.18      paf       136:        append_here+=src_rows_to_copy;
                    137:        fused_rows+=src_rows_to_copy;
1.4       paf       138: 
                    139:        return *this;
                    140: }

E-mail: