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