Annotation of parser3/src/main/pa_array.C, revision 1.20
1.1 paf 1: /*
1.20 ! paf 2: $Id: pa_array.C,v 1.19 2001/02/23 09:43:15 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.13 paf 9: #include "pa_exception.h"
1.1 paf 10:
1.10 paf 11: Array::Array(Pool& apool, int initial_rows) :
1.13 paf 12: Pooled(apool) {
1.6 paf 13: head=tail=static_cast<Chunk *>(
1.17 paf 14: malloc(sizeof(int)+sizeof(Chunk::Row)*initial_rows+sizeof(Chunk *)));
1.6 paf 15: head->count=initial_rows;
1.1 paf 16: append_here=head->rows;
1.6 paf 17: link_row=&head->rows[initial_rows];
1.1 paf 18: link_row->link=0;
19: fused_rows=0;
1.2 paf 20:
1.3 paf 21: cache_chunk_base=0;
22: cache_chunk=head;
1.1 paf 23: }
24:
1.9 paf 25: void Array::expand(int chunk_rows) {
1.20 ! paf 26: if(chunk_rows<CR_INITIAL_ROWS_DEFAULT)
! 27: chunk_rows=CR_INITIAL_ROWS_DEFAULT;
! 28:
1.6 paf 29: Chunk *chunk=tail=static_cast<Chunk *>(
1.17 paf 30: malloc(sizeof(int)+sizeof(Chunk::Row)*chunk_rows+sizeof(Chunk *)));
1.6 paf 31: chunk->count=chunk_rows;
1.1 paf 32: link_row->link=chunk;
33: append_here=chunk->rows;
1.6 paf 34: link_row=&chunk->rows[chunk_rows];
1.1 paf 35: link_row->link=0;
36: }
37:
38:
1.15 paf 39: Array& Array::operator += (Item *src) {
1.1 paf 40: if(chunk_is_full())
1.6 paf 41: expand(tail->count*CR_GROW_PERCENT/100);
1.1 paf 42:
43: append_here->item=src;
44: append_here++; fused_rows++;
45:
46: return *this;
47: }
48:
1.15 paf 49: Array::Item *Array::get(int index) const {
1.3 paf 50: if(!(index>=0 && index<size())) {
1.17 paf 51: THROW(0, 0, 0,
1.12 paf 52: "Array::get(%d) out of range [0..%d]", index, size()-1);
1.10 paf 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.16 paf 70: }
71:
72: void Array::put(int index, Item *item) {
73: if(!(index>=0 && index<size())) {
1.17 paf 74: THROW(0, 0, 0,
1.16 paf 75: "Array::put(%d) out of range [0..%d]", index, size()-1);
76: return;
77: }
78:
79: // if they ask index to the left of cached position, forget cache
80: if(index<cache_chunk_base) {
81: cache_chunk_base=0;
82: cache_chunk=head;
83: }
84:
85: // navigate to chunk with "index" row
86: while(!(index>=cache_chunk_base && index<cache_chunk_base+cache_chunk->count)) {
87: int count=cache_chunk->count;
88: cache_chunk_base+=count;
89: cache_chunk=cache_chunk->rows[count].link;
90: }
91:
92: cache_chunk->rows[index-cache_chunk_base].item=item;
1.4 paf 93: }
94:
1.18 paf 95: Array& Array::append_array(const Array& src, int offset) {
96: int src_rows_to_copy=src.fused_rows-offset;
1.4 paf 97: int last_chunk_rows_left=link_row-append_here;
98:
1.5 paf 99: // our last chunk too small for src to fit?
1.18 paf 100: if(src_rows_to_copy>last_chunk_rows_left) {
1.5 paf 101: // shrink last chunk to used rows
102: tail->count-=last_chunk_rows_left;
103: link_row=append_here;
104:
1.6 paf 105: // append new src_used_rows-ed chunk
1.18 paf 106: expand(src_rows_to_copy);
1.5 paf 107: }
108:
1.18 paf 109: Chunk *src_chunk=src.head;
1.6 paf 110: Chunk::Row *dest_rows=append_here;
1.18 paf 111: int rows_left_to_copy=src.fused_rows;
112: int rows_left_to_skip=offset;
1.6 paf 113: while(true) {
114: int src_count=src_chunk->count;
115: Chunk *next_chunk=src_chunk->rows[src_count].link;
116: if(next_chunk) {
117: // not last source chunk
118: // taking it all
1.18 paf 119: int rows_to_copy_now=src_count-rows_left_to_skip;
120: if(rows_to_copy_now>0)
121: memcpy(dest_rows, src_chunk->rows+rows_left_to_skip,
122: sizeof(Chunk::Row)*rows_to_copy_now);
1.19 paf 123: else
124: rows_left_to_skip-=src_count;
125:
1.18 paf 126: dest_rows+=rows_to_copy_now;
1.6 paf 127: rows_left_to_copy-=src_count;
128: src_chunk=next_chunk;
129: } else {
130: // the last source chunk
131: // taking only those rows of chunk that _left_to_copy
1.18 paf 132: int rows_to_copy_now=rows_left_to_copy-rows_left_to_skip;
133: if(rows_to_copy_now>0)
134: memcpy(dest_rows, src_chunk->rows+rows_left_to_skip,
135: sizeof(Chunk::Row)*rows_to_copy_now);
1.6 paf 136: break;
1.4 paf 137: }
138: }
1.18 paf 139: append_here+=src_rows_to_copy;
140: fused_rows+=src_rows_to_copy;
1.4 paf 141:
142: return *this;
143: }
E-mail: