Beispiel #1
0
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 );
	}
}
Beispiel #2
0
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;
}
Beispiel #3
0
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];
}
Beispiel #4
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 );
}
Beispiel #5
0
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);
}
Beispiel #6
0
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++;
}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}
Beispiel #9
0
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;
}
Beispiel #10
0
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 ];
}
Beispiel #11
0
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
}
Beispiel #12
0
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 ];
}
Beispiel #13
0
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;
}
Beispiel #14
0
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
}
Beispiel #15
0
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);
}
Beispiel #16
0
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 );
}