Diff for /parser3/src/main/Attic/pa_array.C between versions 1.16 and 1.30

version 1.16, 2001/02/21 17:36:58 version 1.30, 2001/03/29 17:11:41
Line 1 Line 1
 /*  /** @file
   $Id$          Parser: array class.
   
           Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
   
           Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
   
           $Id$
 */  */
   
 #include <string.h>  #include "pa_config_includes.h"
   
 #include "pa_pool.h"  #include "pa_pool.h"
 #include "pa_array.h"  #include "pa_array.h"
 #include "pa_exception.h"  #include "pa_exception.h"
   #include "pa_common.h"
   
 Array::Array(Pool& apool, int initial_rows) :  Array::Array(Pool& apool, int initial_rows) :
         Pooled(apool) {          Pooled(apool) {
           initial_rows=min(3, initial_rows);
   
         head=tail=static_cast<Chunk *>(          head=tail=static_cast<Chunk *>(
                 pool().malloc(sizeof(int)+sizeof(Chunk::Row)*initial_rows+sizeof(Chunk *)));                  malloc(sizeof(int)+sizeof(Chunk::Row)*initial_rows+sizeof(Chunk *)));
         head->count=initial_rows;          head->count=initial_rows;
         append_here=head->rows;          append_here=head->rows;
         link_row=&head->rows[initial_rows];          link_row=&head->rows[initial_rows];
Line 23  Array::Array(Pool& apool, int initial_ro Line 32  Array::Array(Pool& apool, int initial_ro
 }  }
   
 void Array::expand(int chunk_rows) {  void Array::expand(int chunk_rows) {
           if(chunk_rows<CR_INITIAL_ROWS_DEFAULT)
                   chunk_rows=CR_INITIAL_ROWS_DEFAULT;
   
         Chunk *chunk=tail=static_cast<Chunk *>(          Chunk *chunk=tail=static_cast<Chunk *>(
                 pool().malloc(sizeof(int)+sizeof(Chunk::Row)*chunk_rows+sizeof(Chunk *)));                  malloc(sizeof(int)+sizeof(Chunk::Row)*chunk_rows+sizeof(Chunk *)));
         chunk->count=chunk_rows;          chunk->count=chunk_rows;
         link_row->link=chunk;          link_row->link=chunk;
         append_here=chunk->rows;          append_here=chunk->rows;
Line 45  Array& Array::operator += (Item *src) { Line 57  Array& Array::operator += (Item *src) {
   
 Array::Item *Array::get(int index) const {  Array::Item *Array::get(int index) const {
         if(!(index>=0 && index<size())) {          if(!(index>=0 && index<size())) {
                 pool().exception().raise(0, 0, 0,                   THROW(0, 0, 0, 
                         "Array::get(%d) out of range [0..%d]", index, size()-1);                          "Array::get(%d) out of range [0..%d]", index, size()-1);
                 return 0;                  return 0;
         }          }
Line 68  Array::Item *Array::get(int index) const Line 80  Array::Item *Array::get(int index) const
   
 void Array::put(int index, Item *item) {  void Array::put(int index, Item *item) {
         if(!(index>=0 && index<size())) {          if(!(index>=0 && index<size())) {
                 pool().exception().raise(0, 0, 0,                   THROW(0, 0, 0, 
                         "Array::put(%d) out of range [0..%d]", index, size()-1);                          "Array::put(%d) out of range [0..%d]", index, size()-1);
                 return;                  return;
         }          }
Line 89  void Array::put(int index, Item *item) { Line 101  void Array::put(int index, Item *item) {
         cache_chunk->rows[index-cache_chunk_base].item=item;          cache_chunk->rows[index-cache_chunk_base].item=item;
 }  }
   
 Array& Array::append_array(const Array& src) {  Array& Array::append_array(const Array& src, int offset) {
         int src_used_rows=src.fused_rows;          int src_rows_to_copy=src.fused_rows-offset;
         int last_chunk_rows_left=link_row-append_here;          int last_chunk_rows_left=link_row-append_here;
                   
         // our last chunk too small for src to fit?          // our last chunk too small for src to fit?
         if(src_used_rows>last_chunk_rows_left) {          if(src_rows_to_copy>last_chunk_rows_left) {
                 // shrink last chunk to used rows                  // shrink last chunk to used rows
                 tail->count-=last_chunk_rows_left;                  tail->count-=last_chunk_rows_left;
                 link_row=append_here;                  link_row=append_here;
   
                 // append new src_used_rows-ed chunk                   // append new src_used_rows-ed chunk 
                 expand(src_used_rows);                  expand(src_rows_to_copy);
         }          }
   
         Chunk *src_chunk=src.head;           Chunk *src_chunk=src.head;
         Chunk::Row *dest_rows=append_here;          Chunk::Row *dest_rows=append_here;
         int rows_left_to_copy=src_used_rows;          int rows_left_to_copy=src.fused_rows;
           int rows_left_to_skip=offset;
         while(true) {          while(true) {
                 int src_count=src_chunk->count;                  int src_count=src_chunk->count;
                 Chunk *next_chunk=src_chunk->rows[src_count].link;                  Chunk *next_chunk=src_chunk->rows[src_count].link;
                 if(next_chunk) {                  if(next_chunk) {
                         // not last source chunk                          // not last source chunk
                         // taking it all                          // taking it all
                         memcpy(dest_rows, src_chunk->rows, sizeof(Chunk::Row)*src_count);                          int rows_to_copy_now=src_count-rows_left_to_skip;
                         dest_rows+=src_count;                          if(rows_to_copy_now>0)
                                   memcpy(dest_rows, src_chunk->rows+rows_left_to_skip, 
                                           sizeof(Chunk::Row)*rows_to_copy_now);
                           else
                                   rows_left_to_skip-=src_count;
   
                           dest_rows+=rows_to_copy_now;
                         rows_left_to_copy-=src_count;                          rows_left_to_copy-=src_count;
                           
                         src_chunk=next_chunk;                          src_chunk=next_chunk;
                 } else {                  } else {
                         // the last source chunk                          // the last source chunk
                         // taking only those rows of chunk that _left_to_copy                          // taking only those rows of chunk that _left_to_copy
                         memcpy(dest_rows, src_chunk->rows, sizeof(Chunk::Row)*rows_left_to_copy);                          int rows_to_copy_now=rows_left_to_copy-rows_left_to_skip;
                           if(rows_to_copy_now>0)
                                   memcpy(dest_rows, src_chunk->rows+rows_left_to_skip, 
                                           sizeof(Chunk::Row)*rows_to_copy_now);
                         break;                          break;
                 }                  }
         }          }
         append_here+=src_used_rows;          append_here+=src_rows_to_copy;
         fused_rows+=src_used_rows;          fused_rows+=src_rows_to_copy;
   
         return *this;          return *this;
 }  }
   
   void Array::for_each(For_each_func func, void *info) const {
           Chunk *chunk=head;
           while(true) {
                   if(chunk==tail) { // last chunk?
                           for(Chunk::Row *row=chunk->rows; row!=append_here; row++)
                                   (*func)(row->item, info);
                           break;
                   } else {
                           int count=chunk->count;
                           for(int i=0; i<count; i++)
                                   (*func)(chunk->rows[i].item, info);
                           chunk=chunk->rows[count].link;
                   }
           }
   }
   
   Array::Item* Array::first_that(First_that_func_const func, const void *info) const {
           Chunk *chunk=head;
           while(true) {
                   if(chunk==tail) { // last chunk?
                           for(Chunk::Row *row=chunk->rows; row!=append_here; row++)
                                   if((*func)(row->item, info))
                                           return row->item;
                           break;
                   } else {
                           int count=chunk->count;
                           for(int i=0; i<count; i++) {
                                   Item* item=chunk->rows[i].item;
                                   if((*func)(item, info))
                                           return item;
                           }
                           chunk=chunk->rows[count].link;
                   }
           }
           return 0;
   }
   
   Array::Item* Array::first_that(First_that_func func, void *info) const {
           Chunk *chunk=head;
           while(true) {
                   if(chunk==tail) { // last chunk?
                           for(Chunk::Row *row=chunk->rows; row!=append_here; row++)
                                   if((*func)(row->item, info))
                                           return row->item;
                           break;
                   } else {
                           int count=chunk->count;
                           for(int i=0; i<count; i++) {
                                   Item* item=chunk->rows[i].item;
                                   if((*func)(item, info))
                                           return item;
                           }
                           chunk=chunk->rows[count].link;
                   }
           }
           return 0;
   }

Removed from v.1.16  
changed lines
  Added in v.1.30


E-mail: