void DaoCinType_DeriveMethods( DaoCinType *self ) { daoint i, k, m, N = self->supers->size; DaoCinType *super; DNode *it; for(i=0; i<N; i++){ super = (DaoCinType*) self->supers->items.pValue[i]; self->citype->bases = DList_New( DAO_DATA_VALUE ); self->vatype->bases = DList_New( DAO_DATA_VALUE ); DList_Append( self->citype->bases, super->citype ); DList_Append( self->vatype->bases, super->vatype ); for(it=DMap_First(super->methods); it; it=DMap_Next( super->methods, it )){ if( it->value.pRoutine->overloads ){ DRoutines *routs = it->value.pRoutine->overloads; for(k=0,m=routs->routines->size; k<m; k++){ DaoRoutine *rout = routs->routines->items.pRoutine[i]; DaoMethods_Insert( self->methods, rout, NULL, self->vatype ); } }else{ DaoMethods_Insert( self->methods, it->value.pRoutine, NULL, self->vatype ); } } } self->derived = 1; }
DaoCinType* DaoCinType_New( DaoInterface *inter, DaoType *target ) { DaoCinType *self = (DaoCinType*) dao_calloc( 1, sizeof(DaoCinType) ); DaoValue_Init( self, DAO_CINTYPE ); self->trait |= DAO_VALUE_DELAYGC; self->derived = 0; self->supers = DList_New( DAO_DATA_VALUE ); self->methods = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE ); self->citype = DaoType_New( "interface<", DAO_CINTYPE, (DaoValue*)self, NULL ); self->vatype = DaoType_New( inter->abtype->name->chars, DAO_CINVALUE, (DaoValue*)self, NULL ); self->abstract = inter; self->target = target; GC_IncRC( self->citype ); GC_IncRC( self->vatype ); GC_IncRC( self->abstract ); GC_IncRC( self->target ); self->citype->nested = DList_New( DAO_DATA_VALUE ); self->vatype->nested = DList_New( DAO_DATA_VALUE ); DList_Append( self->citype->nested, target ); DList_Append( self->vatype->nested, target ); DString_AppendChar( self->vatype->name, '<' ); DString_Append( self->vatype->name, target->name ); DString_AppendChar( self->vatype->name, '>' ); DString_Append( self->citype->name, self->vatype->name ); DString_AppendChar( self->citype->name, '>' ); #ifdef DAO_USE_GC_LOGGER DaoObjectLogger_LogNew( (DaoValue*) self ); #endif return self; }
DaoxTriangulator* DaoxTriangulator_New() { DaoxTriangulator *self = (DaoxTriangulator*) dao_calloc( 1, sizeof(DaoxTriangulator) ); self->points = DArray_New( sizeof(DaoxVector2D) ); self->triangles = DArray_New( sizeof(DaoxTriangle) ); self->vertices = DList_New(0); self->worklist = DList_New(0); return self; }
DaoXmlDOM* DaoXmlDOM_New() { DaoXmlDOM *self = (DaoXmlDOM*) dao_calloc( 1, sizeof(DaoXmlDOM) ); self->root = NULL; self->caches = DList_New(0); return self; }
int DaoInterface_BindTo( DaoInterface *self, DaoType *type, DMap *binds ) { DNode *it; DMap *newbinds = NULL; DList *methods; void *pvoid[2]; daoint i, n, bl; /* XXX locking */ if( type->interfaces == NULL ) type->interfaces = DHash_New( DAO_DATA_VALUE, 0 ); pvoid[0] = type; pvoid[1] = self->abtype; if( (it = DMap_Find( type->interfaces, self )) ) return it->value.pVoid != NULL; if( binds && DMap_Find( binds, pvoid ) ) return 1; if( binds ==NULL ) newbinds = binds = DHash_New( DAO_DATA_VOID2, 0 ); DaoInterface_TempBind( self, type, binds ); methods = DList_New(0); DMap_SortMethods( self->methods, methods ); bl = DaoInterface_CheckBind( methods, type, binds ); DList_Delete( methods ); if( newbinds ) DMap_Delete( newbinds ); DMap_Insert( type->interfaces, self, bl ? self : NULL ); if( bl == 0 ) return 0; for(i=0,n=self->supers->size; i<n; i++){ DaoInterface *super = (DaoInterface*) self->supers->items.pValue[i]; if( DMap_Find( type->interfaces, super ) ) continue; DMap_Insert( type->interfaces, super, super ); } return 1; }
void DCondVar_Init( DCondVar *self ) { self->thdWaiting = DList_New(0); DMutex_Init( & self->thdMutex ); /* manual reset, when signaled, all waiting threads will be waked up: */ self->myCondVar = CreateEvent( NULL, TRUE, FALSE, NULL ); }
/* // Activate all events waiting on a future value: */ void DaoFuture_ActivateEvent( DaoFuture *self ) { DaoCallServer *server = daoCallServer; DList *array = DList_New(0); DNode *node; daoint i; DMutex_Lock( & server->mutex ); for(i=0; i<server->events2->size; ++i){ DaoTaskEvent *event = (DaoTaskEvent*) server->events2->items.pVoid[i]; if( DaoCallServer_CheckEvent( event, self, NULL ) ){ event->state = DAO_EVENT_RESUME; DList_Append( server->events, event ); DList_Erase( server->events2, i, 1 ); i -= 1; } } for(node=DMap_First(server->waitings); node; node=DMap_Next(server->waitings,node)){ DaoTaskEvent *event = (DaoTaskEvent*) node->value.pValue; /* remove from timed waiting list: */ if( DaoCallServer_CheckEvent( event, self, NULL ) ){ event->state = DAO_EVENT_RESUME; DList_Append( server->events, event ); DList_Append( array, node->key.pVoid ); } } for(i=0; i<array->size; i++) DMap_Erase( server->waitings, array->items.pVoid[i] ); DCondVar_Signal( & server->condv ); DMutex_Unlock( & server->mutex ); DList_Delete( array ); }
DaoChannel* DaoChannel_New( DaoType *type, int dtype ) { DaoChannel *self = (DaoChannel*) dao_calloc( 1, sizeof(DaoChannel) ); if( dtype ) type = DaoType_Specialize( dao_type_channel, & type, type != NULL ); DaoCstruct_Init( (DaoCstruct*) self, type ); self->buffer = DList_New( DAO_DATA_VALUE ); return self; }
static DaoCallServer* DaoCallServer_New( DaoVmSpace *vms ) { DaoCallServer *self = (DaoCallServer*)dao_malloc( sizeof(DaoCallServer) ); DMutex_Init( & self->mutex ); DCondVar_Init( & self->condv ); DCondVar_Init( & self->condv2 ); DThread_Init( & self->timer ); self->finishing = 0; self->timing = 0; self->total = 0; self->vacant = 0; self->idle = 0; self->stopped = 0; self->threads = DList_New(0); self->functions = DList_New(0); self->parameters = DList_New(0); self->owners = DList_New(0); self->events = DList_New(0); self->events2 = DList_New(0); self->waitings = DMap_New( DAO_DATA_COMPLEX, 0 ); self->pending = DHash_New(0,0); self->active = DHash_New(0,0); self->caches = DList_New(0); self->vmspace = vms; self->timestamp.real = 0.0; self->timestamp.imag = 0.0; return self; }
DaoxNode* DaoxNode_New( DaoxGraph *graph ) { DaoxNode *self = (DaoxNode*) dao_calloc( 1, sizeof(DaoxNode) ); DaoCstruct_Init( (DaoCstruct*) self, graph->nodeType ); self->graph = graph; self->outs = DList_New(0); self->weight = 1; return self; }
DaoCinType* DaoCinType_New( DaoInterface *inter, DaoType *target ) { DaoCinType *self = (DaoCinType*) dao_calloc( 1, sizeof(DaoCinType) ); DaoNamespace *ns = inter->nameSpace; DString *name = inter->abtype->name; DaoValue_Init( self, DAO_CINTYPE ); self->trait |= DAO_VALUE_DELAYGC; self->derived = 0; self->bases = DList_New( DAO_DATA_VALUE ); self->methods = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE ); self->citype = DaoType_New( ns, "interface<", DAO_CINTYPE, (DaoValue*)self, NULL ); self->vatype = DaoType_New( ns, name->chars, DAO_CINVALUE, (DaoValue*)self, NULL ); self->abstract = inter; self->target = target; self->citype->core = & daoCinTypeCore; self->vatype->core = & daoCinValueCore; GC_IncRC( self->citype ); GC_IncRC( self->vatype ); GC_IncRC( self->abstract ); GC_IncRC( self->target ); self->vatype->kernel = DaoTypeKernel_New( NULL ); self->vatype->kernel->abtype = self->vatype; GC_IncRC( self->vatype->kernel ); GC_IncRC( self->vatype ); self->citype->args = DList_New( DAO_DATA_VALUE ); self->vatype->args = DList_New( DAO_DATA_VALUE ); DList_Append( self->citype->args, target ); DList_Append( self->vatype->args, target ); DString_AppendChar( self->vatype->name, '<' ); DString_Append( self->vatype->name, target->name ); DString_AppendChar( self->vatype->name, '>' ); DString_Append( self->citype->name, self->vatype->name ); DString_AppendChar( self->citype->name, '>' ); #ifdef DAO_USE_GC_LOGGER DaoObjectLogger_LogNew( (DaoValue*) self ); #endif return self; }
DaoxGraph* DaoxGraph_New( DaoType *type, int directed ) { DaoxGraph *self = (DaoxGraph*) dao_calloc( 1, sizeof(DaoxGraph) ); DaoCstruct_Init( (DaoCstruct*) self, type ); self->nodes = DList_New(DAO_DATA_VALUE); self->edges = DList_New(DAO_DATA_VALUE); self->directed = directed; self->nodeType = NULL; self->edgeType = NULL; if( type ){ DaoType **types = type->args->items.pType; daoint count = type->args->size; self->nodeType = DaoType_Specialize( daox_node_template_type, types, count ); self->edgeType = DaoType_Specialize( daox_edge_template_type, types, count ); GC_IncRC( self->nodeType ); GC_IncRC( self->edgeType ); } return self; }
DaoXmlNode* DaoXmlNode_New() { DaoXmlNode *self = (DaoXmlNode*) dao_calloc( 1, sizeof(DaoXmlNode) ); self->parent = NULL; self->children = DList_New(0); self->name = DString_New(); self->content = DString_New(); self->attributes = DHash_New( DAO_DATA_STRING, DAO_DATA_STRING ); return self; }
int DaoRegex_ChangeExt( DaoRegex *self, DString *input, DString *output, DString *target, int index, daoint *start2, daoint *end2 ) { daoint start = start2 ? (daoint) *start2 : 0; daoint end = end2 ? (daoint) *end2 : 0; daoint i, n=0, p1=start, p2=end, p3, last; DaoValue *value = NULL; DaoString matched = {DAO_STRING,0,0,0,0,NULL}; DList *array = DList_New( DAO_DATA_VALUE ); DString *tmp = DString_New(); DString *tmp2 = DString_New(); DString_Reset( output, 0 ); if( self == NULL || input->size == 0 ) goto DoNothing; matched.value = tmp; Dao_ParseTarget( target, array, (DaoValue*) & matched ); if( end == 0 ) end = p2 = DString_Size( input ); n = last = 0; while( DaoRegex_Match( self, input, & p1, & p2 ) ){ n += 1; if( index ==0 || n == index ){ DString_SubString( input, tmp2, last, p1 - last ); DString_Append( output, tmp2 ); DString_Clear( tmp ); for(i=0; i<array->size; i++){ value = array->items.pValue[i]; if( value->type == DAO_INTEGER ){ if( DaoRegex_SubMatch( self, value->xInteger.value, & p1, & p3 ) ){ DString_SubString( input, tmp2, p1, p3 - p1 ); DString_Append( tmp, tmp2 ); } }else{ DString_Append( tmp, value->xString.value ); } } DString_Append( output, tmp ); last = p2; } if( start2 ) *start2 = p1; if( end2 ) *end2 = p2; p1 = p2; p2 = end; if( index && n == index ) break; } DString_SubString( input, tmp2, last, end - last ); DString_Append( output, tmp2 ); DoNothing: DString_Delete( tmp ); DString_Delete( tmp2 ); DList_Delete( array ); return n; }
static double DaoxGraph_MaxFlow_PRTF_Float( DaoxGraph *self, DaoxNode *source, DaoxNode *sink ) { daoint i, n; double inf = 1.0; DList *list = DList_New(0); for(i=0,n=source->outs->size; i<n; i++){ DaoxEdge *edge = source->outs->items.pgEdge[i]; if( source == edge->first ) inf += edge->X.MF->capacity; } for(i=0,n=self->nodes->size; i<n; i++){ DaoxNode *node = self->nodes->items.pgNode[i]; node->X.MF->nextpush = 0; node->X.MF->height = 0; node->X.MF->excess = 0.0; if( node != source && node != sink ) DList_PushBack( list, node ); } source->X.MF->nextpush = 0; source->X.MF->height = n; source->X.MF->excess = inf; for(i=0,n=self->edges->size; i<n; i++){ DaoxEdge *edge = self->edges->items.pgEdge[i]; edge->X.MF->flow_fw = 0.0; edge->X.MF->flow_bw = 0.0; } for(i=0,n=source->outs->size; i<n; i++){ DaoxEdge *edge = source->outs->items.pgEdge[i]; if( source == edge->first ) MaxFlow_PushFloat( source, edge ); } i = 0; while( i < list->size ){ DaoxNode *U = list->items.pgNode[i]; daoint old_height = U->X.MF->height; MaxFlow_DischargeFloat( U ); if( U->X.MF->height > old_height ){ DList_Erase( list, i, 1 ); DList_PushFront( list, U ); i = 0; }else{ i += 1; } } DList_Delete( list ); inf = 0.0; for(i=0,n=source->outs->size; i<n; i++){ DaoxEdge *edge = source->outs->items.pgEdge[i]; if( source == edge->first ) inf += edge->X.MF->flow_fw; } return inf; }
static void NODE_Search( DaoProcess *proc, DaoValue *p[], int N ) { DList *nodes; DaoList *list = DaoProcess_PutList( proc ); DaoxNode *self = (DaoxNode*) p[0]; DaoVmCode *sect = DaoProcess_InitCodeSection( proc, 1 ); daoint method = p[1]->xEnum.value; daoint which = p[2]->xEnum.value; daoint i, j, entry; if( sect == NULL ) return; for(i=0; i<self->graph->nodes->size; i++){ DaoxNode *node = (DaoxNode*) self->graph->nodes->items.pVoid[i]; node->state = 0; } nodes = DList_New(0); DList_PushBack( nodes, self ); entry = proc->topFrame->entry; while( nodes->size ){ DaoxNode *node = NULL; if( method ){ node = (DaoxNode*) DList_Front( nodes ); DList_PopFront( nodes ); }else{ node = (DaoxNode*) DList_Back( nodes ); DList_PopBack( nodes ); } if( node->state ) continue; node->state = 1; if( sect->b >0 ) DaoProcess_SetValue( proc, sect->a, (DaoValue*) node ); proc->topFrame->entry = entry; DaoProcess_Execute( proc ); if( proc->status == DAO_PROCESS_ABORTED ) break; if( proc->stackValues[0]->xInteger.value ){ DaoList_PushBack( list, (DaoValue*) node ); if( which == 0 ) break; } for(j=0; j<node->outs->size; j++){ DaoxEdge *edge = (DaoxEdge*) node->outs->items.pVoid[j]; DaoxNode *node2 = node == edge->first ? edge->second : edge->first; DList_PushBack( nodes, node2 ); } } DaoProcess_PopFrame( proc ); DList_Delete( nodes ); }
DaoInterface* DaoInterface_New( const char *name ) { DaoInterface *self = (DaoInterface*) dao_calloc( 1, sizeof(DaoInterface) ); DaoValue_Init( self, DAO_INTERFACE ); self->trait |= DAO_VALUE_DELAYGC; self->derived = 0; self->supers = DList_New( DAO_DATA_VALUE ); self->methods = DHash_New( DAO_DATA_STRING, DAO_DATA_VALUE ); self->abtype = DaoType_New( name, DAO_INTERFACE, (DaoValue*)self, NULL ); GC_IncRC( self->abtype ); #ifdef DAO_USE_GC_LOGGER DaoObjectLogger_LogNew( (DaoValue*) self ); #endif return self; }
static void GRAPH_ConnectedComponents( DaoProcess *proc, DaoValue *p[], int N ) { DaoxGraph *self = (DaoxGraph*) p[0]; DaoList *graphs = DaoProcess_PutList( proc ); DList *cclist; daoint i, n; if( self->nodes->size == 0 ){ DaoList_PushBack( graphs, (DaoValue*)self ); return; } cclist = DList_New(0); DaoxGraph_ConnectedComponents( self, cclist ); for(i=0,n=cclist->size; i<n; i++) DaoList_PushBack( graphs, cclist->items.pValue[i] ); DList_Delete( cclist ); }
DaoxEdge* DaoxGraph_AddEdge( DaoxGraph *self, DaoxNode *first, DaoxNode *second ) { DaoxEdge *edge = DaoxEdge_New( self ); DList_PushFront( first->outs, edge ); if( self->directed ){ if( second->ins == NULL ) second->ins = DList_New(DAO_DATA_VALUE); DList_PushBack( second->ins, edge ); }else{ DList_PushBack( second->outs, edge ); } DList_Append( self->edges, edge ); edge->first = first; edge->second = second; return edge; }
void DaoxNode_DepthFirstSearch( DaoxNode *self, DList *nodes ) { DList *stack = DList_New(0); daoint j; DList_Clear( nodes ); DList_PushBack( stack, self ); while( stack->size ){ DaoxNode *node = (DaoxNode*) DList_Back( stack ); DList_PopBack( stack ); if( node->state ) continue; node->state = 1; DList_PushBack( nodes, node ); for(j=0; j<node->outs->size; j++){ DaoxEdge *edge = (DaoxEdge*) node->outs->items.pVoid[j]; DaoxNode *node2 = node == edge->first ? edge->second : edge->first; DList_PushBack( stack, node2 ); } } DList_Delete( stack ); }
DaoRoutine* DaoInterface_BindTo( DaoInterface *self, DaoType *type, DMap *binds ) { DNode *it; DMap *newbinds = NULL; DList *methods; DaoRoutine *incompatible; void *pvoid[2]; daoint i, n; if( self->abtype->kernel->SetupMethods ){ DaoTypeKernel *kernel = self->abtype->kernel; kernel->SetupMethods( kernel->nspace, self->abtype->core ); } /* XXX locking */ if( type->interfaces == NULL ){ type->interfaces = DHash_New( DAO_DATA_VALUE, DAO_DATA_VALUE ); } pvoid[0] = type; pvoid[1] = self->abtype; if( (it = DMap_Find( type->interfaces, self )) ) return it->value.pRoutine; if( binds && DMap_Find( binds, pvoid ) ) return NULL; if( binds ==NULL ) newbinds = binds = DHash_New( DAO_DATA_VOID2, 0 ); DaoInterface_TempBind( self, type, binds ); methods = DList_New(0); DMap_SortMethods( self->methods, methods ); incompatible = DaoInterface_CheckBind( methods, type, binds ); DList_Delete( methods ); if( newbinds ) DMap_Delete( newbinds ); DMap_Insert( type->interfaces, self, incompatible ); if( incompatible ) return incompatible; for(i=0,n=self->bases->size; i<n; i++){ DaoInterface *base = (DaoInterface*) self->bases->items.pValue[i]; if( DMap_Find( type->interfaces, base ) ) continue; DMap_Insert( type->interfaces, base, NULL ); } return NULL; }
void DaoInterface_DeriveMethods( DaoInterface *self ) { daoint i, k, m, N = self->bases->size; DaoNamespace *ns = self->nameSpace; DaoInterface *base; DNode *it; for(i=0; i<N; i++){ base = (DaoInterface*) self->bases->items.pValue[i]; if( self->abtype->bases == NULL ) self->abtype->bases = DList_New( DAO_DATA_VALUE ); DList_Append( self->abtype->bases, base->abtype ); for(it=DMap_First(base->methods); it; it=DMap_Next( base->methods, it )){ if( it->value.pRoutine->overloads ){ DRoutines *routs = it->value.pRoutine->overloads; for(k=0,m=routs->routines->size; k<m; k++){ DaoRoutine *rout = routs->routines->items.pRoutine[i]; DaoMethods_Insert( self->methods, rout, ns, self->abtype ); } }else{ DaoMethods_Insert( self->methods, it->value.pRoutine, ns, self->abtype ); } } } self->derived = 1; }
DList* DList_Copy( DList *self ) { DList *copy = DList_New( self->type ); DList_Assign( copy, self ); return copy; }
void DaoxGraph_ConnectedComponents( DaoxGraph *self, DList *cclist ) { DList *nodes; DaoxGraph *subgraph; daoint i, j, k, n; if( self->nodes->size == 0 ){ DList_PushBack( cclist, self ); return; } for(i=0; i<self->nodes->size; i++){ DaoxNode *node = (DaoxNode*) self->nodes->items.pVoid[i]; node->state = 0; } nodes = DList_New(0); while( self->nodes->size ){ DaoxNode_BreadthFirstSearch( (DaoxNode*) self->nodes->items.pVoid[0], nodes ); #if 0 printf( "self->nodes->size = %i, %i\n", self->nodes->size, nodes->size ); #endif if( nodes->size == self->nodes->size ){ DList_PushBack( cclist, self ); break; } subgraph = DaoxGraph_New( self->ctype, self->directed ); DList_PushBack( cclist, subgraph ); for(i=0,n=nodes->size; i<n; i++){ DaoxNode *node = (DaoxNode*) nodes->items.pVoid[i]; GC_Assign( & node->graph, subgraph ); DList_PushBack( subgraph->nodes, node ); for(j=0; j<node->outs->size; j++){ DaoxEdge *edge = (DaoxEdge*) node->outs->items.pVoid[j]; if( edge->graph == subgraph ) continue; GC_Assign( & edge->graph, subgraph ); DList_PushBack( subgraph->edges, edge ); } } for(i=0,k=0,n=self->nodes->size; i<n; i++){ DaoxNode *node = (DaoxNode*) self->nodes->items.pVoid[i]; /* Ensure no duplication of the reference (for the Concurrent GC): */ self->nodes->items.pVoid[i] = NULL; if( node->graph != self ){ GC_DecRC( node ); continue; } self->nodes->items.pVoid[k++] = node; } self->nodes->size = k; for(i=0,k=0,n=self->edges->size; i<n; i++){ DaoxNode *edge = (DaoxNode*) self->edges->items.pVoid[i]; /* Ensure no duplication of the reference (for the Concurrent GC): */ self->edges->items.pVoid[i] = NULL; if( edge->graph != self ){ GC_DecRC( edge ); continue; } self->edges->items.pVoid[k++] = edge; } self->edges->size = k; } DList_Delete( nodes ); }