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

1.1       paf         1: /*
1.7     ! paf         2:   $Id: pa_array.C,v 1.6 2001/01/29 10:15:04 paf Exp $
1.1       paf         3: */
                      4: 
                      5: #include <string.h>
                      6: 
                      7: #include "pa_pool.h"
                      8: 
                      9: void *Array::operator new(size_t size, Pool *apool) {
                     10:        return apool->malloc(size);
                     11: }
                     12: 
1.7     ! paf        13: Array::Array(Pool *apool, int initial_rows) :
        !            14:        pool(apool) {
1.6       paf        15:        head=tail=static_cast<Chunk *>(
                     16:                pool->malloc(sizeof(int)+sizeof(Chunk::Row)*initial_rows+sizeof(Chunk *)));
                     17:        head->count=initial_rows;
1.1       paf        18:        append_here=head->rows;
1.6       paf        19:        link_row=&head->rows[initial_rows];
1.1       paf        20:        link_row->link=0;
                     21:        fused_rows=0;
1.2       paf        22: 
1.3       paf        23:        cache_chunk_base=0;
                     24:        cache_chunk=head;
1.1       paf        25: }
                     26: 
1.6       paf        27: void Array::expand(int chunk_rows) {
                     28:        Chunk *chunk=tail=static_cast<Chunk *>(
                     29:                pool->malloc(sizeof(int)+sizeof(Chunk::Row)*chunk_rows+sizeof(Chunk *)));
                     30:        chunk->count=chunk_rows;
1.1       paf        31:        link_row->link=chunk;
                     32:        append_here=chunk->rows;
1.6       paf        33:        link_row=&chunk->rows[chunk_rows];
1.1       paf        34:        link_row->link=0;
                     35: }
                     36: 
                     37: 
                     38: Array& Array::operator += (Item src) {
                     39:        if(chunk_is_full())
1.6       paf        40:                expand(tail->count*CR_GROW_PERCENT/100);
1.1       paf        41: 
                     42:        append_here->item=src;
                     43:        append_here++; fused_rows++;
                     44: 
                     45:        return *this;
                     46: }
                     47: 
1.2       paf        48: Array::Item& Array::operator [] (int index) {
1.3       paf        49:        if(!(index>=0 && index<size())) {
                     50:                // FIX: some sort of thread-global error
                     51:                Item *result=0;
                     52:                return *result;
1.2       paf        53:        }
                     54: 
1.3       paf        55:        // if they ask index to the left of cached position, forget cache
                     56:        if(index<cache_chunk_base) {
                     57:                cache_chunk_base=0;
                     58:                cache_chunk=head;
                     59:        }
                     60: 
                     61:        // navigate to chunk with "index" row
                     62:        while(!(index>=cache_chunk_base && index<cache_chunk_base+cache_chunk->count)) {
                     63:                int count=cache_chunk->count;
                     64:                cache_chunk_base+=count;
                     65:                cache_chunk=cache_chunk->rows[count].link;
                     66:        }
                     67: 
                     68:        return cache_chunk->rows[index-cache_chunk_base].item;
1.4       paf        69: }
                     70: 
                     71: Array& Array::operator += (Array& src) {
1.6       paf        72:        int src_used_rows=src.fused_rows;
1.4       paf        73:        int last_chunk_rows_left=link_row-append_here;
                     74:        
1.5       paf        75:        // our last chunk too small for src to fit?
1.6       paf        76:        if(src_used_rows>last_chunk_rows_left) {
1.5       paf        77:                // shrink last chunk to used rows
                     78:                tail->count-=last_chunk_rows_left;
                     79:                link_row=append_here;
                     80: 
1.6       paf        81:                // append new src_used_rows-ed chunk 
                     82:                expand(src_used_rows);
1.5       paf        83:        }
                     84: 
1.6       paf        85:        Chunk *src_chunk=src.head; 
                     86:        Chunk::Row *dest_rows=append_here;
                     87:        int rows_left_to_copy=src_used_rows;
                     88:        while(true) {
                     89:                int src_count=src_chunk->count;
                     90:                Chunk *next_chunk=src_chunk->rows[src_count].link;
                     91:                if(next_chunk) {
                     92:                        // not last source chunk
                     93:                        // taking it all
                     94:                        memcpy(dest_rows, src_chunk->rows, sizeof(Chunk::Row)*src_count);
                     95:                        dest_rows+=src_count;
                     96:                        rows_left_to_copy-=src_count;
                     97:                        
                     98:                        src_chunk=next_chunk;
                     99:                } else {
                    100:                        // the last source chunk
                    101:                        // taking only those rows of chunk that _left_to_copy
                    102:                        memcpy(dest_rows, src_chunk->rows, sizeof(Chunk::Row)*rows_left_to_copy);
                    103:                        break;
1.4       paf       104:                }
                    105:        }
1.6       paf       106:        append_here+=src_used_rows;
                    107:        fused_rows+=src_used_rows;
1.4       paf       108: 
                    109:        return *this;
                    110: }

E-mail: