Annotation of parser3/src/main/pa_array.C, revision 1.47

1.23      paf         1: /** @file
1.24      paf         2:        Parser: array class.
                      3: 
1.46      paf         4:        Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)
1.47    ! paf         5:        Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.24      paf         6: 
1.47    ! paf         7:        $Id: pa_array.C,v 1.46 2002/02/08 07:27:46 paf Exp $
1.1       paf         8: */
                      9: 
                     10: #include "pa_pool.h"
1.8       paf        11: #include "pa_array.h"
1.13      paf        12: #include "pa_exception.h"
1.30      paf        13: #include "pa_common.h"
1.1       paf        14: 
1.45      paf        15: void Array::construct_new(int initial_rows) {
1.6       paf        16:        head=tail=static_cast<Chunk *>(
1.41      paf        17:                malloc(sizeof(int)+sizeof(Chunk::Row)*initial_rows+sizeof(Chunk *), 19));
1.6       paf        18:        head->count=initial_rows;
1.1       paf        19:        append_here=head->rows;
1.6       paf        20:        link_row=&head->rows[initial_rows];
1.1       paf        21:        link_row->link=0;
                     22:        fused_rows=0;
1.45      paf        23: }
                     24: 
                     25: Array::Array(Pool& apool, int initial_rows) : Pooled(apool) {
                     26:        construct_new(max(initial_rows, CR_INITIAL_ROWS_DEFAULT));
                     27: }
                     28: 
                     29: Array::Array(const Array& source, int offset) : Pooled(source.pool()) {
                     30:        construct_new(source.size());
                     31:        append_array(source, offset);
1.1       paf        32: }
                     33: 
1.9       paf        34: void Array::expand(int chunk_rows) {
1.6       paf        35:        Chunk *chunk=tail=static_cast<Chunk *>(
1.41      paf        36:                malloc(sizeof(int)+sizeof(Chunk::Row)*chunk_rows+sizeof(Chunk *), 2));
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.32      parser     47:                expand(tail->count+CR_GROW_COUNT);
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.40      parser     57:                throw Exception(0, 0, 0, 
1.12      paf        58:                        "Array::get(%d) out of range [0..%d]", index, size()-1);
1.33      parser     59:                return 0; // never
1.2       paf        60:        }
                     61: 
1.42      paf        62:        int base=0;
                     63:        Chunk *chunk=head;
1.3       paf        64: 
                     65:        // navigate to chunk with "index" row
1.42      paf        66:        while(!(index>=base && index<base+chunk->count)) {
                     67:                int count=chunk->count;
                     68:                base+=count;
                     69:                chunk=chunk->rows[count].link;
1.3       paf        70:        }
                     71: 
1.42      paf        72:        return chunk->rows[index-base].item;
1.16      paf        73: }
                     74: 
                     75: void Array::put(int index, Item *item) {
                     76:        if(!(index>=0 && index<size())) {
1.40      parser     77:                throw Exception(0, 0, 0, 
1.16      paf        78:                        "Array::put(%d) out of range [0..%d]", index, size()-1);
1.33      parser     79:                return; // never
1.16      paf        80:        }
                     81: 
1.42      paf        82:        int base=0;
                     83:        Chunk *chunk=head;
1.16      paf        84: 
                     85:        // navigate to chunk with "index" row
1.42      paf        86:        while(!(index>=base && index<base+chunk->count)) {
                     87:                int count=chunk->count;
                     88:                base+=count;
                     89:                chunk=chunk->rows[count].link;
1.16      paf        90:        }
                     91: 
1.42      paf        92:        chunk->rows[index-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;
1.26      paf       143: }
                    144: 
1.28      paf       145: void Array::for_each(For_each_func func, void *info) const {
1.26      paf       146:        Chunk *chunk=head;
                    147:        while(true) {
                    148:                if(chunk==tail) { // last chunk?
                    149:                        for(Chunk::Row *row=chunk->rows; row!=append_here; row++)
                    150:                                (*func)(row->item, info);
                    151:                        break;
                    152:                } else {
                    153:                        int count=chunk->count;
                    154:                        for(int i=0; i<count; i++)
                    155:                                (*func)(chunk->rows[i].item, info);
                    156:                        chunk=chunk->rows[count].link;
                    157:                }
                    158:        }
                    159: }
1.44      paf       160: 
                    161: /*void Array::for_each(For_each_func_storage func, void *info) {
                    162:        Chunk *chunk=head;
                    163:        while(true) {
                    164:                if(chunk==tail) { // last chunk?
                    165:                        for(Chunk::Row *row=chunk->rows; row!=append_here; row++)
                    166:                                (*func)(&row->item, info);
                    167:                        break;
                    168:                } else {
                    169:                        int count=chunk->count;
                    170:                        for(int i=0; i<count; i++)
                    171:                                (*func)(&chunk->rows[i].item, info);
                    172:                        chunk=chunk->rows[count].link;
                    173:                }
                    174:        }
                    175: }
                    176: */
1.26      paf       177: 
1.31      paf       178: /*void Array::for_each(For_each_func_const func, const void *info) const {
                    179:        Chunk *chunk=head;
                    180:        while(true) {
                    181:                if(chunk==tail) { // last chunk?
                    182:                        for(Chunk::Row *row=chunk->rows; row!=append_here; row++)
                    183:                                (*func)(row->item, info);
                    184:                        break;
                    185:                } else {
                    186:                        int count=chunk->count;
                    187:                        for(int i=0; i<count; i++)
                    188:                                (*func)(chunk->rows[i].item, info);
                    189:                        chunk=chunk->rows[count].link;
                    190:                }
                    191:        }
                    192: }
                    193: */
1.38      parser    194: void* Array::first_that(Item_that_func_const func, const void *info) const {
1.29      paf       195:        Chunk *chunk=head;
                    196:        while(true) {
                    197:                if(chunk==tail) { // last chunk?
                    198:                        for(Chunk::Row *row=chunk->rows; row!=append_here; row++)
1.38      parser    199:                                if(void *result=(*func)(row->item, info))
                    200:                                        return result;
1.29      paf       201:                        break;
                    202:                } else {
                    203:                        int count=chunk->count;
                    204:                        for(int i=0; i<count; i++) {
                    205:                                Item* item=chunk->rows[i].item;
1.38      parser    206:                                if(void *result=(*func)(item, info))
                    207:                                        return result;
1.29      paf       208:                        }
                    209:                        chunk=chunk->rows[count].link;
                    210:                }
                    211:        }
                    212:        return 0;
                    213: }
                    214: 
1.38      parser    215: void* Array::first_that(Item_that_func func, void *info) const {
1.26      paf       216:        Chunk *chunk=head;
                    217:        while(true) {
                    218:                if(chunk==tail) { // last chunk?
                    219:                        for(Chunk::Row *row=chunk->rows; row!=append_here; row++)
1.38      parser    220:                                if(void *result=(*func)(row->item, info))
                    221:                                        return result;
1.26      paf       222:                        break;
                    223:                } else {
                    224:                        int count=chunk->count;
1.27      paf       225:                        for(int i=0; i<count; i++) {
                    226:                                Item* item=chunk->rows[i].item;
1.38      parser    227:                                if(void *result=(*func)(item, info))
                    228:                                        return result;
1.27      paf       229:                        }
1.26      paf       230:                        chunk=chunk->rows[count].link;
                    231:                }
                    232:        }
                    233:        return 0;
1.4       paf       234: }

E-mail: