--- parser3/src/main/Attic/pa_array.C 2001/01/27 15:21:05 1.2 +++ parser3/src/main/Attic/pa_array.C 2001/10/19 12:43:30 1.40 @@ -1,46 +1,47 @@ -/* - $Id: pa_array.C,v 1.2 2001/01/27 15:21:05 paf Exp $ -*/ - -#include +/** @file + Parser: array class. -#include "pa_pool.h" + Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) + Author: Alexander Petrosyan (http://design.ru/paf) -void *Array::operator new(size_t size, Pool *apool) { - return apool->malloc(size); -} + $Id: pa_array.C,v 1.40 2001/10/19 12:43:30 parser Exp $ +*/ -void Array::construct(Pool *apool, int initial_rows) { - pool=apool; - curr_chunk_rows=initial_rows; - head=static_cast( - pool->malloc(sizeof(int)+sizeof(Chunk::Row)*curr_chunk_rows+sizeof(Chunk *))); +#include "pa_pool.h" +#include "pa_array.h" +#include "pa_exception.h" +#include "pa_common.h" + +Array::Array(Pool& apool, int initial_rows) : + Pooled(apool) { + initial_rows=max(initial_rows, CR_INITIAL_ROWS_DEFAULT); + + head=tail=static_cast( + malloc(sizeof(int)+sizeof(Chunk::Row)*initial_rows+sizeof(Chunk *))); + head->count=initial_rows; append_here=head->rows; - link_row=&head->rows[curr_chunk_rows]; + link_row=&head->rows[initial_rows]; link_row->link=0; fused_rows=0; - cache_index=0; - cache_row=0; - cache_countdown=curr_chunk_rows; - cache_link_row=link_row; + cache_chunk_base=0; + cache_chunk=head; } -void Array::expand() { - curr_chunk_rows+=curr_chunk_rows*CR_GROW_PERCENT/100; - Chunk *chunk=static_cast( - pool->malloc(sizeof(int)+sizeof(Chunk::Row)*curr_chunk_rows+sizeof(Chunk *))); - chunk->count=curr_chunk_rows; +void Array::expand(int chunk_rows) { + Chunk *chunk=tail=static_cast( + malloc(sizeof(int)+sizeof(Chunk::Row)*chunk_rows+sizeof(Chunk *))); + chunk->count=chunk_rows; link_row->link=chunk; append_here=chunk->rows; - link_row=&chunk->rows[curr_chunk_rows]; + link_row=&chunk->rows[chunk_rows]; link_row->link=0; } -Array& Array::operator += (Item src) { +Array& Array::operator += (Item *src) { if(chunk_is_full()) - expand(); + expand(tail->count+CR_GROW_COUNT); append_here->item=src; append_here++; fused_rows++; @@ -48,46 +49,172 @@ Array& Array::operator += (Item src) { return *this; } -/* -char *Array::c_str() { - char *result=static_cast(pool->malloc(size()+1)); - - char *copy_here=result; - Chunk *chunk=&head; - do { - Chunk::Row *row=chunk->rows; - for(int i=0; icount; i++) { - if(row==append_here) - goto break2; - - memcpy(copy_here, row->item.ptr, row->item.size); - copy_here+=row->item.size; - row++; +Array::Item *Array::get(int index) const { + if(!(index>=0 && index=cache_chunk_base && indexcount)) { + int count=cache_chunk->count; + cache_chunk_base+=count; + cache_chunk=cache_chunk->rows[count].link; + } + + return cache_chunk->rows[index-cache_chunk_base].item; +} + +void Array::put(int index, Item *item) { + if(!(index>=0 && index=cache_chunk_base && indexcount)) { + int count=cache_chunk->count; + cache_chunk_base+=count; + cache_chunk=cache_chunk->rows[count].link; + } + + cache_chunk->rows[index-cache_chunk_base].item=item; +} + +Array& Array::append_array(const Array& src, int offset) { + int src_rows_to_copy=src.fused_rows-offset; + int last_chunk_rows_left=link_row-append_here; + + // our last chunk too small for src to fit? + if(src_rows_to_copy>last_chunk_rows_left) { + // shrink last chunk to used rows + tail->count-=last_chunk_rows_left; + link_row=append_here; + + // append new src_used_rows-ed chunk + expand(src_rows_to_copy); + } + + Chunk *src_chunk=src.head; + Chunk::Row *dest_rows=append_here; + int rows_left_to_copy=src.fused_rows; + int rows_left_to_skip=offset; + while(true) { + int src_count=src_chunk->count; + Chunk *next_chunk=src_chunk->rows[src_count].link; + if(next_chunk) { + // not last source chunk + // taking it all + int rows_to_copy_now=src_count-rows_left_to_skip; + if(rows_to_copy_now>0) + memcpy(dest_rows, src_chunk->rows+rows_left_to_skip, + sizeof(Chunk::Row)*rows_to_copy_now); + else + rows_left_to_skip-=src_count; + + dest_rows+=rows_to_copy_now; + rows_left_to_copy-=src_count; + src_chunk=next_chunk; + } else { + // the last source chunk + // taking only those rows of chunk that _left_to_copy + int rows_to_copy_now=rows_left_to_copy-rows_left_to_skip; + if(rows_to_copy_now>0) + memcpy(dest_rows, src_chunk->rows+rows_left_to_skip, + sizeof(Chunk::Row)*rows_to_copy_now); + break; } - chunk=row->link; - } while(chunk); -break2: - *copy_here=0; - return result; + } + append_here+=src_rows_to_copy; + fused_rows+=src_rows_to_copy; + + return *this; } -*/ -/* -void Array::put(int index, Item item) { + +void Array::for_each(For_each_func func, void *info) const { + Chunk *chunk=head; + while(true) { + if(chunk==tail) { // last chunk? + for(Chunk::Row *row=chunk->rows; row!=append_here; row++) + (*func)(row->item, info); + break; + } else { + int count=chunk->count; + for(int i=0; irows[i].item, info); + chunk=chunk->rows[count].link; + } + } } -Array::Item Array::get(int index) { +/*void Array::for_each(For_each_func_const func, const void *info) const { + Chunk *chunk=head; + while(true) { + if(chunk==tail) { // last chunk? + for(Chunk::Row *row=chunk->rows; row!=append_here; row++) + (*func)(row->item, info); + break; + } else { + int count=chunk->count; + for(int i=0; irows[i].item, info); + chunk=chunk->rows[count].link; + } + } } */ - -Array::Item& Array::operator [] (int index) { - // we have cached row&index? - if(index>=cache_index && indexrows; row!=append_here; row++) + if(void *result=(*func)(row->item, info)) + return result; + break; + } else { + int count=chunk->count; + for(int i=0; irows[i].item; + if(void *result=(*func)(item, info)) + return result; + } + chunk=chunk->rows[count].link; + } } + return 0; +} - int cache_index; - Chunk::Row *cache_row; - int cache_countdown; - Chunk::Row *cache_link_row; - +void* Array::first_that(Item_that_func func, void *info) const { + Chunk *chunk=head; + while(true) { + if(chunk==tail) { // last chunk? + for(Chunk::Row *row=chunk->rows; row!=append_here; row++) + if(void *result=(*func)(row->item, info)) + return result; + break; + } else { + int count=chunk->count; + for(int i=0; irows[i].item; + if(void *result=(*func)(item, info)) + return result; + } + chunk=chunk->rows[count].link; + } + } return 0; -} \ No newline at end of file +}