Annotation of parser3/src/main/pa_array.C, revision 1.8
1.1 paf 1: /*
1.8 ! paf 2: $Id: pa_array.C,v 1.7 2001/01/29 15:56:04 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.1 paf 9:
1.8 ! paf 10: template<class Item>
! 11: void *Array<Item>::operator new(size_t size, Pool *apool) {
1.1 paf 12: return apool->malloc(size);
13: }
14:
1.8 ! paf 15: template<class Item>
! 16: Array<Item>::Array(Pool *apool, int initial_rows) :
1.7 paf 17: pool(apool) {
1.6 paf 18: head=tail=static_cast<Chunk *>(
19: pool->malloc(sizeof(int)+sizeof(Chunk::Row)*initial_rows+sizeof(Chunk *)));
20: head->count=initial_rows;
1.1 paf 21: append_here=head->rows;
1.6 paf 22: link_row=&head->rows[initial_rows];
1.1 paf 23: link_row->link=0;
24: fused_rows=0;
1.2 paf 25:
1.3 paf 26: cache_chunk_base=0;
27: cache_chunk=head;
1.1 paf 28: }
29:
1.8 ! paf 30: template<class Item>
! 31: void Array<Item>::expand(int chunk_rows) {
1.6 paf 32: Chunk *chunk=tail=static_cast<Chunk *>(
33: pool->malloc(sizeof(int)+sizeof(Chunk::Row)*chunk_rows+sizeof(Chunk *)));
34: chunk->count=chunk_rows;
1.1 paf 35: link_row->link=chunk;
36: append_here=chunk->rows;
1.6 paf 37: link_row=&chunk->rows[chunk_rows];
1.1 paf 38: link_row->link=0;
39: }
40:
41:
1.8 ! paf 42: template<class Item>
! 43: Array<Item>& Array<Item>::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.8 ! paf 53: template<class Item>
! 54: Item& Array<Item>::operator [] (int index) {
1.3 paf 55: if(!(index>=0 && index<size())) {
56: // FIX: some sort of thread-global error
57: Item *result=0;
58: return *result;
1.2 paf 59: }
60:
1.3 paf 61: // if they ask index to the left of cached position, forget cache
62: if(index<cache_chunk_base) {
63: cache_chunk_base=0;
64: cache_chunk=head;
65: }
66:
67: // navigate to chunk with "index" row
68: while(!(index>=cache_chunk_base && index<cache_chunk_base+cache_chunk->count)) {
69: int count=cache_chunk->count;
70: cache_chunk_base+=count;
71: cache_chunk=cache_chunk->rows[count].link;
72: }
73:
74: return cache_chunk->rows[index-cache_chunk_base].item;
1.4 paf 75: }
76:
1.8 ! paf 77: template<class Item>
! 78: Array<Item>& Array<Item>::operator += (Array& src) {
1.6 paf 79: int src_used_rows=src.fused_rows;
1.4 paf 80: int last_chunk_rows_left=link_row-append_here;
81:
1.5 paf 82: // our last chunk too small for src to fit?
1.6 paf 83: if(src_used_rows>last_chunk_rows_left) {
1.5 paf 84: // shrink last chunk to used rows
85: tail->count-=last_chunk_rows_left;
86: link_row=append_here;
87:
1.6 paf 88: // append new src_used_rows-ed chunk
89: expand(src_used_rows);
1.5 paf 90: }
91:
1.6 paf 92: Chunk *src_chunk=src.head;
93: Chunk::Row *dest_rows=append_here;
94: int rows_left_to_copy=src_used_rows;
95: while(true) {
96: int src_count=src_chunk->count;
97: Chunk *next_chunk=src_chunk->rows[src_count].link;
98: if(next_chunk) {
99: // not last source chunk
100: // taking it all
101: memcpy(dest_rows, src_chunk->rows, sizeof(Chunk::Row)*src_count);
102: dest_rows+=src_count;
103: rows_left_to_copy-=src_count;
104:
105: src_chunk=next_chunk;
106: } else {
107: // the last source chunk
108: // taking only those rows of chunk that _left_to_copy
109: memcpy(dest_rows, src_chunk->rows, sizeof(Chunk::Row)*rows_left_to_copy);
110: break;
1.4 paf 111: }
112: }
1.6 paf 113: append_here+=src_used_rows;
114: fused_rows+=src_used_rows;
1.4 paf 115:
116: return *this;
117: }
E-mail: