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: