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