Annotation of parser3/src/main/pa_array.C, revision 1.6
1.1 paf 1: /*
1.6 ! paf 2: $Id: pa_array.C,v 1.5 2001/01/29 09:57:22 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:
13: void Array::construct(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: