#include <oops.h> #include "standard.h" #include "circular_buffer.h" #include "linked_chunk.h" pool linked_chunk::ThePool (sizeof(linked_chunk)) ; pool cursor::ThePool (sizeof(cursor)) ; char * linked_chunk::version = "Objects Plus Linked Chunk Version 1.0" ; char * cursor::version = "Objects Plus Cursor Version 1.0" ; linked_chunk::linked_chunk() { next = NULL ; storage = new circular_buffer() ; } linked_chunk::~linked_chunk() { next = NULL ; delete storage ; Boolean linked_chunk::bounds(natural n) { return ((0<=n)&&(n<length()));> }; linked_chunk * linked_chunk::location(natural n) { natural l = storage->length() ; if (n >= l) {return (next) ? next->location(n - l):NULL;}; return this; } natural linked_chunk::length() { return storage->length() + ( next ? next->length() : 0 ) ; } ; Boolean linked_chunk::full() { return false; } ; Boolean linked_chunk::empty() { return storage->empty() && ( next ? next->empty() : true ); } ; void *linked_chunk::peak(natural n) { natural l = storage->length() ; if (n >= l) {return (next) ? next->peak(n - l) : NULL ;}; return storage->peak(n) ; } void * linked_chunk::get(natural n) { natural l = storage->length() ; if ( n >= l ) { return next ? next->get(n-l) : NULL ; } return storage->get(n) ; } void linked_chunk::expand(natural n) { // get a new fixed chunk of storage and add to the end of this chunk linked_chunk * c = new linked_chunk () ; c->next = next ; next = c ; if (n == 0) { circular_buffer * f = c->storage; c->storage = storage ; storage = f ; return ; } natural l = storage->length() ; natural limit = (l+1)/2 ; for(natural i=0 ; i<= limit ; i++ ) { c->storage->set(i,storage->get(limit)); } } void linked_chunk::set(natural n,void * e) { // does it belong here and there is room? natural l = storage->length() ; if ((! storage->full()) && (0 <= n) && ( n <= l )) { storage->set(n,e); return; } // does it belong in the next chunk? if ((n >= l)&&(next)) { next->set(n-l,e) ; return ; } // does it belong at the end of the array? if so, make room and store if ((n == l)&&(!next)) { next = new linked_chunk() ; next->set(n-l,e) ; return ; } // fail soft, out of bounds store, just ignore if ((n > l)&&(!next)) { return ; } // make room and store expand(n); set(n,e); } void linked_chunk::replace(natural n,void * e) { // is this the chunk or is it the next one? natural l = storage->length() ; if ((0 <= n) && ( n < l )) { storage->replace(n,e); return; } // this is the chunk, replace this one element if ((n >= l)&&(next)) { next->replace(n-l,e) ; return ; } } linked_chunk * linked_chunk::shrink(){ if (empty()) { linked_chunk * n = next ; delete this ; return (n ? n->shrink() : NULL) ; } if (next) next = next->shrink() ; return this; } natural linked_chunk::offset(linked_chunk *c) { if (this==c) return 0; return storage->length() + ( next ? next->offset(c) : 0 ) ; } Boolean linked_chunk::test(){ Boolean results ; natural i; linked_chunk * cp ; void* a[7*CHUNK_SIZE] ; natural length; Boolean empty ; Boolean full ; results = true ; // simple create and delete test cp = new linked_chunk(); length = cp->length(); results &= (length==0) ; delete cp ; // store all nils and check to see if they all come back nil // test set,peak,length,offset cp = new linked_chunk(); for(i=0;i<7*CHUNK_SIZE;i++) {cp->set(i,NULL) ;} for(i=0;i<7*CHUNK_SIZE;i++) {results = results && (NULL == cp->peak(i)) ;} length = cp->length(); results &= (length==7*CHUNK_SIZE) ; natural base = cp->offset(cp) ; results &= (base==0) ; base = cp->offset(cp->next) ; results &= (base==cp->storage->length()) ; base = cp->offset(NULL) ; results &= (base==cp->length()) ; delete cp ; // store more unique data in each cell and check cp = new linked_chunk(); for(i=0;i<7*CHUNK_SIZE;i++) { cp->set(i,(void *)i) ; a[i] = cp->peak(i) ; } for(i=0;i<7*CHUNK_SIZE;i++) { results = results && (a[i] == cp->peak(i)) ; } length = cp->length(); results &= (length==7*CHUNK_SIZE) ; delete cp ; // store nils and check, test empty, full, length cp = new linked_chunk(); for(i=0;i<7*CHUNK_SIZE;i++) {cp->set(i,nil) ;} for(i=0;i<7*CHUNK_SIZE;i++) {results = results && (NULL == cp->peak(i)) ;} length = cp->length(); results &= (length==7*CHUNK_SIZE) ; empty = cp->empty(); full = cp->full(); results &= (empty == false) ; results &= (full == false) ; delete cp ; cp = new linked_chunk(); for(i=0;i<7*CHUNK_SIZE;i++) { cp->set(i,(void *)i) ; a[i] = cp->peak(i) ; } for(i=0;i<7*CHUNK_SIZE;i++) { results = results && (a[i] == cp->peak(i)) ; } length = cp->length(); results &= (length==7*CHUNK_SIZE) ; empty = cp->empty(); full = cp->full(); results &= (empty == false) ; results &= (full == false) ; delete cp ; void * e ; cp = new linked_chunk(); for(i=0;i<7*CHUNK_SIZE;i++) { cp->set(0,(void *)i) ; length = cp->length(); results &= (length==1) ; empty = cp->empty(); full = cp->full(); results &= (empty == false) ; results &= (full == false) ; e = cp->get(0); results &= e == (void *)i ; length = cp->length(); results &= (length==0) ; empty = cp->empty(); full = cp->full(); results &= (empty == true) ; results &= (full == false) ; } delete cp ; cp = new linked_chunk(); for(i=0;i<7*CHUNK_SIZE;i++) { cp->set(0,(void *)i) ; } length = cp->length(); results &= (length==7*CHUNK_SIZE) ; empty = cp->empty(); full = cp->full(); results &= (empty == false) ; results &= (full == false) ; for(i=0;i<7*CHUNK_SIZE;i++) { e = cp->get(cp->length()-1); results &= e == (void *)i ; } length = cp->length(); results &= (length==0) ; empty = cp->empty(); full = cp->full(); results &= (empty == true) ; results &= (full == false) ; cp = cp->shrink(); results &= (cp == NULL); delete cp ; cp = new linked_chunk(); for(i=0;i<7*CHUNK_SIZE;i++) { cp->set(i,(void *)i) ; } for(i=0;i<(7*CHUNK_SIZE);i++) { e = cp->peak(i) ; results &= (e == (void *)i) ; e = cp->get(i) ; results &= (e == (void *)i) ; cp->set(i,(void *)(2*i)) ; } for(i=0;i<(7*CHUNK_SIZE);i++) { e = cp->peak(i) ; results &= (e == (void *)(2*i)) ; } length = cp->length(); results &= (length==7*CHUNK_SIZE) ; empty = cp->empty(); full = cp->full(); results &= (empty == false) ; results &= (full == false) ; delete cp ; // calculate the chunk in the list that materilizes the location cp = new linked_chunk(); for(i=0;i<7*CHUNK_SIZE;i++) { cp->set(i,(void *)i) ; } cursor *c ; linked_chunk * temp ; natural j ; for(i=0;i<7*CHUNK_SIZE;i++) { c = cp->point(0,i) ; results &= (c->offset == (CHUNK_SIZE)*(i / (CHUNK_SIZE))) ; temp = cp ; j = i ; while (j> CHUNK_SIZE-1) { temp = temp->next ; j -= CHUNK_SIZE ; } results &= (c->base == temp); delete c ; } delete cp ; return results ; } cursor * linked_chunk::point(natural offset, natural n) { natural l = storage->length() ; if ((n >= l)&&(next)) return next->point(offset+l, n - l) ; cursor * c = new cursor() ; c->offset = offset ; c->base = this ; return c; }; cursor::cursor() { offset = 0 ; base = NULL ; }; cursor::~cursor() { offset = 0 ; base = NULL ; };
makefile
IDE
var
This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)