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

1.1       paf         1: /*
1.11    ! paf         2:   $Id: pa_array.C,v 1.10 2001/01/29 20:10:32 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.10      paf         9: #include "pa_error.h"
1.1       paf        10: 
1.10      paf        11: void *Array::operator new(size_t size, Pool& apool) {
                     12:        return apool.malloc(size);
1.1       paf        13: }
                     14: 
1.10      paf        15: Array::Array(Pool& apool, int initial_rows) :
1.7       paf        16:        pool(apool) {
1.6       paf        17:        head=tail=static_cast<Chunk *>(
1.10      paf        18:                pool.malloc(sizeof(int)+sizeof(Chunk::Row)*initial_rows+sizeof(Chunk *)));
1.6       paf        19:        head->count=initial_rows;
1.1       paf        20:        append_here=head->rows;
1.6       paf        21:        link_row=&head->rows[initial_rows];
1.1       paf        22:        link_row->link=0;
                     23:        fused_rows=0;
1.2       paf        24: 
1.3       paf        25:        cache_chunk_base=0;
                     26:        cache_chunk=head;
1.1       paf        27: }
                     28: 
1.9       paf        29: void Array::expand(int chunk_rows) {
1.6       paf        30:        Chunk *chunk=tail=static_cast<Chunk *>(
1.10      paf        31:                pool.malloc(sizeof(int)+sizeof(Chunk::Row)*chunk_rows+sizeof(Chunk *)));
1.6       paf        32:        chunk->count=chunk_rows;
1.1       paf        33:        link_row->link=chunk;
                     34:        append_here=chunk->rows;
1.6       paf        35:        link_row=&chunk->rows[chunk_rows];
1.1       paf        36:        link_row->link=0;
                     37: }
                     38: 
                     39: 
1.11    ! paf        40: Array& Array::operator += (const Item *src) {
1.1       paf        41:        if(chunk_is_full())
1.6       paf        42:                expand(tail->count*CR_GROW_PERCENT/100);
1.1       paf        43: 
                     44:        append_here->item=src;
                     45:        append_here++; fused_rows++;
                     46: 
                     47:        return *this;
                     48: }
                     49: 
1.11    ! paf        50: const Array::Item *Array::get(int index) const {
1.3       paf        51:        if(!(index>=0 && index<size())) {
1.10      paf        52:                Error::die("Array::get out of range");
                     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.4       paf        70: }
                     71: 
1.11    ! paf        72: Array& Array::append_array(const Array& src) {
1.6       paf        73:        int src_used_rows=src.fused_rows;
1.4       paf        74:        int last_chunk_rows_left=link_row-append_here;
                     75:        
1.5       paf        76:        // our last chunk too small for src to fit?
1.6       paf        77:        if(src_used_rows>last_chunk_rows_left) {
1.5       paf        78:                // shrink last chunk to used rows
                     79:                tail->count-=last_chunk_rows_left;
                     80:                link_row=append_here;
                     81: 
1.6       paf        82:                // append new src_used_rows-ed chunk 
                     83:                expand(src_used_rows);
1.5       paf        84:        }
                     85: 
1.6       paf        86:        Chunk *src_chunk=src.head; 
                     87:        Chunk::Row *dest_rows=append_here;
                     88:        int rows_left_to_copy=src_used_rows;
                     89:        while(true) {
                     90:                int src_count=src_chunk->count;
                     91:                Chunk *next_chunk=src_chunk->rows[src_count].link;
                     92:                if(next_chunk) {
                     93:                        // not last source chunk
                     94:                        // taking it all
                     95:                        memcpy(dest_rows, src_chunk->rows, sizeof(Chunk::Row)*src_count);
                     96:                        dest_rows+=src_count;
                     97:                        rows_left_to_copy-=src_count;
                     98:                        
                     99:                        src_chunk=next_chunk;
                    100:                } else {
                    101:                        // the last source chunk
                    102:                        // taking only those rows of chunk that _left_to_copy
                    103:                        memcpy(dest_rows, src_chunk->rows, sizeof(Chunk::Row)*rows_left_to_copy);
                    104:                        break;
1.4       paf       105:                }
                    106:        }
1.6       paf       107:        append_here+=src_used_rows;
                    108:        fused_rows+=src_used_rows;
1.4       paf       109: 
                    110:        return *this;
                    111: }

E-mail: