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

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

E-mail: