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

1.1       paf         1: /*
1.14    ! paf         2:   $Id: pa_array.C,v 1.13 2001/02/11 11:27:25 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.14    ! paf        14:                pool().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.14    ! paf        27:                pool().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.11      paf        36: Array& Array::operator += (const 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.11      paf        46: const Array::Item *Array::get(int index) const {
1.3       paf        47:        if(!(index>=0 && index<size())) {
1.14    ! paf        48:                pool().exception().raise(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.4       paf        67: }
                     68: 
1.11      paf        69: Array& Array::append_array(const Array& src) {
1.6       paf        70:        int src_used_rows=src.fused_rows;
1.4       paf        71:        int last_chunk_rows_left=link_row-append_here;
                     72:        
1.5       paf        73:        // our last chunk too small for src to fit?
1.6       paf        74:        if(src_used_rows>last_chunk_rows_left) {
1.5       paf        75:                // shrink last chunk to used rows
                     76:                tail->count-=last_chunk_rows_left;
                     77:                link_row=append_here;
                     78: 
1.6       paf        79:                // append new src_used_rows-ed chunk 
                     80:                expand(src_used_rows);
1.5       paf        81:        }
                     82: 
1.6       paf        83:        Chunk *src_chunk=src.head; 
                     84:        Chunk::Row *dest_rows=append_here;
                     85:        int rows_left_to_copy=src_used_rows;
                     86:        while(true) {
                     87:                int src_count=src_chunk->count;
                     88:                Chunk *next_chunk=src_chunk->rows[src_count].link;
                     89:                if(next_chunk) {
                     90:                        // not last source chunk
                     91:                        // taking it all
                     92:                        memcpy(dest_rows, src_chunk->rows, sizeof(Chunk::Row)*src_count);
                     93:                        dest_rows+=src_count;
                     94:                        rows_left_to_copy-=src_count;
                     95:                        
                     96:                        src_chunk=next_chunk;
                     97:                } else {
                     98:                        // the last source chunk
                     99:                        // taking only those rows of chunk that _left_to_copy
                    100:                        memcpy(dest_rows, src_chunk->rows, sizeof(Chunk::Row)*rows_left_to_copy);
                    101:                        break;
1.4       paf       102:                }
                    103:        }
1.6       paf       104:        append_here+=src_used_rows;
                    105:        fused_rows+=src_used_rows;
1.4       paf       106: 
                    107:        return *this;
                    108: }

E-mail: