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

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

E-mail: