void Dao_Buffer_Resize( Dao_Buffer *self, size_t size ) { self->size = size; if( self->size + 1 >= self->bufsize ){ self->bufsize = self->size + self->bufsize * 0.1 + 1; self->buffer.pVoid = dao_realloc( self->buffer.pVoid, self->bufsize ); }else if( self->size < self->bufsize * 0.75 ){ self->bufsize = self->bufsize * 0.8 + 1; self->buffer.pVoid = dao_realloc( self->buffer.pVoid, self->bufsize ); } }
void* DArray_PopFront( DArray *self ) { void *ret, **buf = self->items.pVoid - self->offset; size_t moffset = 0xffff; if( self->size == 0 ) return NULL; self->size --; self->offset ++; ret = self->items.pVoid[0]; if( self->type ) DArray_DeleteItem( self, self->items.pVoid[0] ); self->items.pVoid ++; if( self->offset >= moffset ){ int locked = self->type == DAO_DATA_VALUE ? DaoGC_LockArray( self ) : 0; self->offset /= 2; memmove( buf + self->offset, self->items.pVoid, self->size*sizeof(void*) ); self->items.pVoid = buf + self->offset; DaoGC_UnlockArray( self, locked ); }else if( self->size < 0.5 * self->bufsize && self->size + 10 < self->bufsize ){ int locked = self->type == DAO_DATA_VALUE ? DaoGC_LockArray( self ) : 0; if( self->offset < 0.1 * self->bufsize ){ /* shrink from back */ self->bufsize = 0.6 * self->bufsize + 1; }else{ /* shrink from front */ self->offset = (size_t)(0.05 * self->bufsize); memmove( buf + self->offset, self->items.pVoid, self->size*sizeof(void*) ); } buf = (void**) dao_realloc( buf, (self->bufsize+1)*sizeof(void*) ); self->items.pVoid = buf + self->offset; DaoGC_UnlockArray( self, locked ); } if( self->type ) return NULL; return ret; }
void* DArray_PushFront( DArray *self, void *val ) { void **buf = self->items.pVoid - self->offset; if( self->offset > 0 ){ /* make sure the concurrent gc won't access an invalid pointer: */ self->items.pVoid[-1] = NULL; self->items.pVoid --; }else{ size_t moffset = 0xffff; size_t offset = self->bufsize/5 + 5; int locked = self->type == DAO_DATA_VALUE ? DaoGC_LockArray( self ) : 0; self->offset = offset < moffset ? offset : moffset; self->bufsize += self->offset; buf = (void**) dao_realloc( buf, (self->bufsize+1)*sizeof(void*) ); memmove( buf + self->offset, buf, self->size*sizeof(void*) ); self->items.pVoid = buf + self->offset - 1; DaoGC_UnlockArray( self, locked ); } if( self->type && val != NULL ){ self->items.pVoid[0] = DArray_CopyItem( self, val ); }else{ self->items.pVoid[0] = val; } self->size ++; self->offset --; return self->items.pVoid[0]; }
void DArray_Erase( DArray *self, daoint start, daoint n ) { void **buf = self->items.pVoid - self->offset; daoint rest, locked; if( start >= self->size ) return; if( n < 0 ) n = self->size; if( n > self->size - start ) n = self->size - start; if( n == 1 ){ if( start == 0 ){ DArray_PopFront( self ); return; }else if( start == self->size -1 ){ DArray_PopBack( self ); return; } } DArray_DeleteItems( self, start, start+n ); rest = self->size - start - n; locked = self->type == DAO_DATA_VALUE ? DaoGC_LockArray( self ) : 0; memmove( self->items.pVoid + start, self->items.pVoid + start + n, rest * sizeof(void*) ); self->size -= n; if( self->size < 0.5*self->bufsize && self->size + 10 < self->bufsize ){ if( self->offset ) memmove( buf, self->items.pVoid, self->size * sizeof(void*)); self->bufsize = 0.6 * self->bufsize + 1; self->items.pVoid = (void**) dao_realloc( buf, (self->bufsize+1)*sizeof(void*) ); self->offset = 0; } DaoGC_UnlockArray( self, locked ); }
void DArray_InsertArray( DArray *self, daoint at, DArray *array, daoint id, daoint n ) { void **buf = self->items.pVoid - self->offset; void **objs = array->items.pVoid; daoint i; assert( self->type == array->type ); assert( self->type != DAO_DATA_VALUE ); if( n < 0 ) n = array->size; n += id; if( n > array->size ) n = array->size; if( n ==0 || id >= array->size ) return; if( (daoint)(self->offset + self->size + n-id) >= self->bufsize ){ if( self->offset > 0 ) memmove( buf, self->items.pVoid, self->size*sizeof(void*) ); self->bufsize += self->bufsize/5 + 1 + ( n - id ); self->items.pVoid = (void**) dao_realloc( buf, (self->bufsize+1)*sizeof(void*) ); self->offset = 0; } if( self->type ){ if( at >= self->size ){ for(i=id; i<n; i++) self->items.pVoid[ self->size+i-id ] = DArray_CopyItem( self, objs[i] ); }else{ memmove( self->items.pVoid+at+(n-id), self->items.pVoid+at, (self->size-at)*sizeof(void*) ); for(i=id; i<n; i++) self->items.pVoid[ at+i-id ] = DArray_CopyItem( self, objs[i] ); } }else{ if( at >= self->size ){ for(i=id; i<n; i++) self->items.pVoid[ self->size+i-id ] = objs[i]; }else{ memmove( self->items.pVoid+at+(n-id), self->items.pVoid+at, (self->size-at)*sizeof(void*) ); for(i=id; i<n; i++) self->items.pVoid[ at+i-id ] = objs[i]; } } self->size += (n-id); }
void DArray_Insert( DArray *self, void *val, daoint id ) { void **buf = self->items.pVoid - self->offset; daoint i; if( id == 0 ){ DArray_PushFront( self, val ); return; }else if( id >= self->size ){ DArray_PushBack( self, val ); return; } if( (daoint)(self->offset + self->size + 1) >= self->bufsize ){ int locked = self->type == DAO_DATA_VALUE ? DaoGC_LockArray( self ) : 0; if( self->offset > 0 ) memmove( buf, self->items.pVoid, self->size*sizeof(void*) ); self->bufsize += self->bufsize/5 + 5; self->items.pVoid = (void**) dao_realloc( buf, (self->bufsize+1)*sizeof(void*) ); self->offset = 0; DaoGC_UnlockArray( self, locked ); } if( self->type && val != NULL ){ int locked = self->type == DAO_DATA_VALUE ? DaoGC_LockArray( self ) : 0; for( i=self->size; i>id; i-- ) self->items.pVoid[i] = self->items.pVoid[i-1]; DaoGC_UnlockArray( self, locked ); self->items.pVoid[ id ] = DArray_CopyItem( self, val ); }else{ for( i=self->size; i>id; i-- ) self->items.pVoid[i] = self->items.pVoid[i-1]; self->items.pVoid[id] = val; } self->size++; }
void DArray_Resize( DArray *self, daoint size, void *val ) { void **buf = self->items.pVoid - self->offset; daoint i; if( size == self->size && self->bufsize>0 ) return; DArray_DeleteItems( self, size, self->size ); if( self->offset ){ daoint min = size > self->size ? self->size : size; int locked = self->type == DAO_DATA_VALUE ? DaoGC_LockArray( self ) : 0; memmove( buf, self->items.pVoid, min*sizeof(void*) ); self->items.pVoid = buf; self->offset = 0; DaoGC_UnlockArray( self, locked ); } /* When resize() is called, probably this is the intended size, * not to be changed frequently. */ if( size >= self->bufsize || size < self->bufsize /2 ){ int locked = self->type == DAO_DATA_VALUE ? DaoGC_LockArray( self ) : 0; self->bufsize = size; self->items.pVoid = (void**) dao_realloc( buf, self->bufsize*sizeof(void*) ); DaoGC_UnlockArray( self, locked ); } if( self->type && val != NULL ){ for(i=self->size; i<size; i++ ) self->items.pVoid[i] = DArray_CopyItem( self, val ); }else{ for(i=self->size; i<size; i++ ) self->items.pVoid[i] = val; } self->size = size; }
void DVector_Resize( DVector *self, daoint size ) { if( self->capacity != size ){ self->capacity = size; self->data.base = dao_realloc( self->data.base, self->capacity*self->stride ); } self->size = size; }
static int* DString_Realloc( DString *self, daoint bufsize ) { daoint bsize = (bufsize + 1)*sizeof(char) + self->sharing*sizeof(int); int *data, *data2; data = data2 = (int*)self->chars - self->sharing; if( data == dao_string ) data = NULL; data = (int*)dao_realloc( data, bsize ); self->chars = (char*)(data + self->sharing); if( data2 == dao_string ) self->chars[ self->size ] = '\0'; if( self->sharing && data2 == dao_string ) data[0] = 1; return data; }
void* DArray_PushBack( DArray *self, void *val ) { void **buf = self->items.pVoid - self->offset; if( (daoint)(self->offset + self->size + 1) >= self->bufsize ){ int locked = self->type == DAO_DATA_VALUE ? DaoGC_LockArray( self ) : 0; self->bufsize += self->bufsize/5 + 5; buf = (void**) dao_realloc( buf, (self->bufsize+1)*sizeof(void*) ); self->items.pVoid = buf + self->offset; DaoGC_UnlockArray( self, locked ); } if( self->type && val != NULL ){ self->items.pVoid[ self->size ] = DArray_CopyItem( self, val ); }else{ self->items.pVoid[ self->size ] = val; } self->size++; return self->items.pVoid[ self->size - 1 ]; }
static void DStringAux_Update( DStringAux *self, DString *string ) { daoint size = 0; DCounter dummy = {7, 0, 0, 0}; DCounter *last = & dummy; uchar_t *bytes = (unsigned char*) string->chars; daoint i = 0; self->size = 0; self->chars = 0; self->visit = 0; while( i < string->size ){ daoint pos = DString_LocateChar( string, i, 0 ); int width = pos == DAO_NULLPOS ? 1 : DString_UTF8CharSize( bytes[i] ); if( width == last->width ){ last->count += 1; }else{ daoint chars = last->chars + last->count; daoint bytes = last->bytes + last->count * last->width; if( size == self->cap ){ self->cap += 1.25 * self->cap + 5; self->counters = (DCounter*) dao_realloc( self->counters, self->cap*sizeof(DCounter) ); } last = self->counters + (size++); last->width = width; last->count = 1; last->chars = chars; last->bytes = bytes; } self->chars += 1; i += width; } self->size = size; /* set after done, for thread safety; */ #if 0 printf( "counters: %i; chars: %i; bytes: %i\n", (int) size, self->chars, string->size ); for(i=0; i<self->size; ++i){ DCounter *c = self->counters + i; printf( "%5i: %2i %5i %5i %5i\n", i, c->width, c->count, c->chars, c->bytes ); } #endif }
void* DList_PushBack( DList *self, void *val ) { void **buf = self->items.pVoid - self->offset; if( self->type == DAO_DATA_VALUE ) DaoGC_LockData(); if( (daoint)(self->offset + self->size + 1) >= self->bufsize ){ self->bufsize += self->bufsize/5 + 5; buf = (void**) dao_realloc( buf, (self->bufsize+1)*sizeof(void*) ); self->items.pVoid = buf + self->offset; } if( self->type && val != NULL ){ self->items.pVoid[ self->size ] = NULL; }else{ self->items.pVoid[ self->size ] = val; } if( self->type == DAO_DATA_VALUE ) DaoGC_UnlockData(); if( self->type && val != NULL ){ self->items.pVoid[ self->size ] = DList_CopyItem( self, val ); } self->size++; return self->items.pVoid[ self->size - 1 ]; }
void* DList_PopBack( DList *self ) { void *ret, **buf = self->items.pVoid - self->offset; if( self->size == 0 ) return NULL; self->size --; ret = self->items.pVoid[ self->size ]; if( self->type ) DList_DeleteItem( self, self->items.pVoid[ self->size ] ); if( self->type == DAO_DATA_VALUE ) DaoGC_LockData(); if( self->size < 0.5 * self->bufsize && self->size + 10 < self->bufsize ){ if( self->offset < 0.1 * self->bufsize ){ /* shrink from back */ self->bufsize = 0.6 * self->bufsize + 1; }else{ /* shrink from front */ self->offset = (size_t)(0.05 * self->bufsize); memmove( buf + self->offset, self->items.pVoid, self->size*sizeof(void*) ); } buf = (void**) dao_realloc( buf, (self->bufsize+1)*sizeof(void*) ); self->items.pVoid = buf + self->offset; } if( self->type == DAO_DATA_VALUE ) DaoGC_UnlockData(); if( self->type ) return NULL; return ret; }
void DString_SetSharing( DString *self, int sharing ) { int *data = (int*)self->chars - self->sharing; if( (self->sharing == 0) == (sharing == 0) ) return; if( sharing && data == dao_string ){ self->sharing = 1; return; /* OK for sharing; */ } DString_Detach( self, self->bufSize ); data = (int*)self->chars - self->sharing; self->sharing = sharing != 0; #ifdef DAO_WITH_THREAD DMutex_Lock( & mutex_string_sharing ); #endif if( sharing ==0 ){ memmove( data, self->chars, self->size*sizeof(char) ); self->bufSize += sizeof(int)/sizeof(char); self->chars = (char*) data; self->chars[ self->size ] = 0; }else{ if( self->bufSize < self->size + (daoint)(sizeof(int)/sizeof(char)) ){ size_t size = (self->size + 1)*sizeof(char) + sizeof(int); if( data == dao_string ) data = NULL; data = (int*) dao_realloc( data, size ); self->bufSize = self->size; } self->chars = (char*)(data + 1); memmove( self->chars, data, self->size*sizeof(char) ); self->chars[ self->size ] = 0; data[0] = 1; } #ifdef DAO_WITH_THREAD DMutex_Unlock( & mutex_string_sharing ); #endif }
void DList_InsertList( DList *self, daoint at, DList *list, daoint id, daoint n ) { void **buf = self->items.pVoid - self->offset; void **objs = list->items.pVoid; daoint i; assert( self->type == list->type ); if( n < 0 ) n = list->size; n += id; if( n > list->size ) n = list->size; if( n ==0 || id >= list->size ) return; if( self->type == DAO_DATA_VALUE ) DaoGC_LockData(); if( (daoint)(self->offset + self->size + n-id) >= self->bufsize ){ if( self->offset > 0 ) memmove( buf, self->items.pVoid, self->size*sizeof(void*) ); self->bufsize += self->bufsize/5 + 1 + ( n - id ); self->items.pVoid = (void**) dao_realloc( buf, (self->bufsize+1)*sizeof(void*) ); self->offset = 0; } if( at < self->size ){ memmove( self->items.pVoid+at+(n-id), self->items.pVoid+at, (self->size-at)*sizeof(void*) ); memset( self->items.pVoid + at, 0, (n-id)*sizeof(void*) ); } if( self->type == DAO_DATA_VALUE ) DaoGC_UnlockData(); if( self->type ){ if( at >= self->size ){ for(i=id; i<n; i++) self->items.pVoid[ self->size+i-id ] = DList_CopyItem( self, objs[i] ); }else{ for(i=id; i<n; i++) self->items.pVoid[ at+i-id ] = DList_CopyItem( self, objs[i] ); } }else{ if( at >= self->size ){ for(i=id; i<n; i++) self->items.pVoid[ self->size+i-id ] = objs[i]; }else{ for(i=id; i<n; i++) self->items.pVoid[ at+i-id ] = objs[i]; } } self->size += (n-id); }
void DVector_Reserve( DVector *self, daoint size ) { if( size <= self->capacity ) return; self->capacity = 1.2 * size + 4; self->data.base = dao_realloc( self->data.base, self->capacity*self->stride ); }