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