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

1.1       paf         1: /*
1.17    ! paf         2:   $Id: pa_array.C,v 1.16 2001/02/21 17:36:58 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.11      paf        92: Array& Array::append_array(const Array& src) {
1.6       paf        93:        int src_used_rows=src.fused_rows;
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.6       paf        97:        if(src_used_rows>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 
                    103:                expand(src_used_rows);
1.5       paf       104:        }
                    105: 
1.6       paf       106:        Chunk *src_chunk=src.head; 
                    107:        Chunk::Row *dest_rows=append_here;
                    108:        int rows_left_to_copy=src_used_rows;
                    109:        while(true) {
                    110:                int src_count=src_chunk->count;
                    111:                Chunk *next_chunk=src_chunk->rows[src_count].link;
                    112:                if(next_chunk) {
                    113:                        // not last source chunk
                    114:                        // taking it all
                    115:                        memcpy(dest_rows, src_chunk->rows, sizeof(Chunk::Row)*src_count);
                    116:                        dest_rows+=src_count;
                    117:                        rows_left_to_copy-=src_count;
                    118:                        
                    119:                        src_chunk=next_chunk;
                    120:                } else {
                    121:                        // the last source chunk
                    122:                        // taking only those rows of chunk that _left_to_copy
                    123:                        memcpy(dest_rows, src_chunk->rows, sizeof(Chunk::Row)*rows_left_to_copy);
                    124:                        break;
1.4       paf       125:                }
                    126:        }
1.6       paf       127:        append_here+=src_used_rows;
                    128:        fused_rows+=src_used_rows;
1.4       paf       129: 
                    130:        return *this;
                    131: }

E-mail: