/* Find the node which occurs immediately after the best matching node */ DLRBT_Node *BLI_dlrbTree_search_next (DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data) { DLRBT_Node *node; /* check that there is a comparator to use */ // TODO: if no comparator is supplied, try using the one supplied with the tree... if (cmp_cb == NULL) return NULL; /* get the node which best matches this description */ node= BLI_dlrbTree_search(tree, cmp_cb, search_data); if (node) { /* if the item we're searching for is less than the node found, we've found the match */ if (cmp_cb(node, search_data) < 0) return node; /* return the previous node otherwise */ // NOTE: what happens if there is no previous node? return node->next; } /* nothing matching was found */ return NULL; }
void write_comb_c(fstream &f) { cout<<"Combinations are being processed.........\nPlease Wait........"; char cb[6][3][3],cb_n[6][3][3],cb_o[6][3][3]; int max_mv=0; long int s=0,cur_rec; cb_comb c,c_n,c_o; f.open("combinat.dat",ios::in|ios::binary|ios::nocreate); f.seekg(-sizeof(c),ios::end); f.read((char*)(&c),sizeof(c)); f.close(); max_mv=c.r_moves()-1; f.open("combinat.dat",ios::in|ios::binary|ios::nocreate); f.seekg(0); while(f.read((char*)(&c),sizeof(c))) if(max_mv==c.r_moves()) { cur_rec=(f.tellg()/sizeof(c))-1; break; } f.close(); cout<<cur_rec; getch(); c.cpy_cube(cb); while(max_mv==c.r_moves()) { for(int i=0;i<6;i++) for(int j=0;j<2;j++) { c_n.new_comb(cb,v[i],dr[j],max_mv); c_n.cpy_cube(cb_n); s=0; f.open("combinat.dat",ios::in|ios::binary|ios::nocreate); f.seekg(0); while(f.read((char*)(&c_o),sizeof(c))) { c_o.cpy_cube(cb_o); if(c_o.r_moves()<=c_n.r_moves()) s+=cmp_cb(cb_n,cb_o); if(s>0) break; } f.close(); if(s==0) { f.open("combinat.dat",ios::app|ios::binary|ios::nocreate); f.write((char*)(&c_n),sizeof(c)); f.close(); } } cur_rec++; f.open("combinat.dat",ios::in|ios::binary|ios::nocreate); f.seekg(sizeof(c)*cur_rec); f.read((char*)(&c),sizeof(c)); c.cpy_cube(cb); f.close(); } return; }
void* sfpr_list_find(sfpr_list_t* list,int(*cmp_cb)(void* data,void* param),void* param) { sfpr_list_node_t* node = list->head; sfpr_mutex_lock(&list->mutex); while(node) { if(cmp_cb(node->data,param) == 0){ sfpr_mutex_unlock(&list->mutex); return node->data; } node = node->next; } sfpr_mutex_unlock(&list->mutex); return NULL; }
/* Find the node which exactly matches the required data */ DLRBT_Node *BLI_dlrbTree_search_exact(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data) { DLRBT_Node *node = (tree) ? tree->root : NULL; short found = 0; /* check that there is a comparator to use */ /* TODO: if no comparator is supplied, try using the one supplied with the tree... */ if (cmp_cb == NULL) { return NULL; } /* iteratively perform this search */ while (node && found == 0) { /* check if traverse further or not * NOTE: it is assumed that the values will be unit values only */ switch (cmp_cb(node, search_data)) { case -1: /* data less than node */ if (node->left) { node = node->left; } else { found = -1; } break; case 1: /* data greater than node */ if (node->right) { node = node->right; } else { found = -1; } break; default: /* data equals node */ found = 1; break; } } /* return the exactly matching node */ return (found == 1) ? (node) : (NULL); }
// NOTE: for duplicates, the update_cb is called (if available), and the existing node is returned DLRBT_Node *BLI_dlrbTree_add(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, DLRBT_NAlloc_FP new_cb, DLRBT_NUpdate_FP update_cb, void *data) { DLRBT_Node *parNode, *node=NULL; short new_node = 0; /* sanity checks */ if (tree == NULL) return NULL; // TODO: if no comparator is supplied, try using the one supplied with the tree... if (cmp_cb == NULL) return NULL; // TODO: if no allocator is supplied, try using the one supplied with the tree... if (new_cb == NULL) return NULL; // TODO: if no updater is supplied, try using the one supplied with the tree... /* try to find the nearest node to this one */ parNode= BLI_dlrbTree_search(tree, cmp_cb, data); /* add new node to the BST in the 'standard way' as appropriate * NOTE: we do not support duplicates in our tree... */ if (parNode) { /* check how this new node compares with the existing ones * NOTE: it is assumed that the values will be unit values only */ switch (cmp_cb(parNode, data)) { case -1: /* add new node as left child */ { node= new_cb(data); new_node= 1; parNode->left= node; node->parent= parNode; } break; case 1: /* add new node as right child */ { node= new_cb(data); new_node= 1; parNode->right= node; node->parent= parNode; } break; default: /* update the duplicate node as appropriate */ { if (update_cb) update_cb(parNode, data); } break; } } else { /* no nodes in the tree yet... add a new node as the root */ node= new_cb(data); new_node= 1; tree->root= node; } /* if a new node was added, it should be tagged as red, and then balanced as appropriate */ if (new_node) { /* tag this new node as being 'red' */ node->tree_col= DLRBT_RED; /* perform BST balancing steps: * start from case 1, an trek through the tail-recursive insertion checks */ insert_check_1(tree, node); } /* return the node added */ return node; }
int sfpr_list_delete(sfpr_list_t *list, int(*cmp_cb)(void *src, void *cmp_param), void *cmp_param, void(*delete_cb)(void *data,void *delete_param),void *delete_param) { sfpr_list_node_t *q ,*p; if(list->head == NULL) { return SFPR_ERROR; } sfpr_mutex_lock(&list->mutex); if(!cmp_cb){ cmp_cb = list_cmp_cb_default; } if(!delete_cb){ delete_cb = list_delete_cb_default; } if(cmp_cb(list->head->data, cmp_param) == 0) /**< 要删除的数据为头结点数据*/ { p = list->head; list->head = list->head->next; delete_cb(p->data, delete_param); if(list->pool){ sfpr_mem_free(list->pool,p); }else{ free(p); } list->count--; sfpr_mutex_unlock(&list->mutex); return SFPR_SUCCESS; } p = list->head; q = list->head->next; while(q != list->tail->next) /**< 否则*/ { if(cmp_cb(q->data, cmp_param) == 0) { q = p->next; p->next = q->next; delete_cb(p->data, delete_param); if(list->pool){ sfpr_mem_free(list->pool,q); }else{ free(q); } list->count--; break; } else { p = p->next; q = q->next; } if(q == NULL) { sfpr_mutex_unlock(&list->mutex); return SFPR_ERROR; } } sfpr_mutex_unlock(&list->mutex); return SFPR_SUCCESS; }
static struct timespec make_deadline(int timeout_millis) { struct timeval start = ast_tvnow(); struct timeval delta = { .tv_sec = timeout_millis / 1000, .tv_usec = (timeout_millis % 1000) * 1000, }; struct timeval deadline_tv = ast_tvadd(start, delta); struct timespec deadline = { .tv_sec = deadline_tv.tv_sec, .tv_nsec = 1000 * deadline_tv.tv_usec, }; return deadline; } struct stasis_message_sink *stasis_message_sink_create(void) { RAII_VAR(struct stasis_message_sink *, sink, NULL, ao2_cleanup); sink = ao2_alloc(sizeof(*sink), stasis_message_sink_dtor); if (!sink) { return NULL; } ast_mutex_init(&sink->lock); ast_cond_init(&sink->cond, NULL); sink->max_messages = 4; sink->messages = ast_malloc(sizeof(*sink->messages) * sink->max_messages); if (!sink->messages) { return NULL; } ao2_ref(sink, +1); return sink; } /*! * \brief Implementation of the stasis_message_sink_cb() callback. * * Why the roundabout way of exposing this via stasis_message_sink_cb()? Well, * it has to do with how we load modules. * * Modules have their own metadata compiled into them in the module info block * at the end of the file. This includes dependency information in the * \c nonoptreq field. * * Asterisk loads the module, inspects the field, then loads any needed * dependencies. This works because Asterisk passes \c RTLD_LAZY to the initial * dlopen(), which defers binding function references until they are called. * * But when you take the address of a function, that function needs to be * available at load time. So if some module used the address of * message_sink_cb() directly, and \c res_stasis_test.so wasn't loaded yet, then * that module would fail to load. * * The stasis_message_sink_cb() function gives us a layer of indirection so that * the initial lazy binding will still work as expected. */ static void message_sink_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message) { struct stasis_message_sink *sink = data; SCOPED_MUTEX(lock, &sink->lock); if (stasis_subscription_final_message(sub, message)) { sink->is_done = 1; ast_cond_signal(&sink->cond); return; } if (stasis_subscription_change_type() == stasis_message_type(message)) { /* Ignore subscription changes */ return; } if (sink->num_messages == sink->max_messages) { size_t new_max_messages = sink->max_messages * 2; struct stasis_message **new_messages = ast_realloc( sink->messages, sizeof(*new_messages) * new_max_messages); if (!new_messages) { return; } sink->max_messages = new_max_messages; sink->messages = new_messages; } ao2_ref(message, +1); sink->messages[sink->num_messages++] = message; ast_cond_signal(&sink->cond); } stasis_subscription_cb stasis_message_sink_cb(void) { return message_sink_cb; } int stasis_message_sink_wait_for_count(struct stasis_message_sink *sink, int num_messages, int timeout_millis) { struct timespec deadline = make_deadline(timeout_millis); SCOPED_MUTEX(lock, &sink->lock); while (sink->num_messages < num_messages) { int r = ast_cond_timedwait(&sink->cond, &sink->lock, &deadline); if (r == ETIMEDOUT) { break; } if (r != 0) { ast_log(LOG_ERROR, "Unexpected condition error: %s\n", strerror(r)); break; } } return sink->num_messages; } int stasis_message_sink_should_stay(struct stasis_message_sink *sink, int num_messages, int timeout_millis) { struct timespec deadline = make_deadline(timeout_millis); SCOPED_MUTEX(lock, &sink->lock); while (sink->num_messages == num_messages) { int r = ast_cond_timedwait(&sink->cond, &sink->lock, &deadline); if (r == ETIMEDOUT) { break; } if (r != 0) { ast_log(LOG_ERROR, "Unexpected condition error: %s\n", strerror(r)); break; } } return sink->num_messages; } int stasis_message_sink_wait_for(struct stasis_message_sink *sink, int start, stasis_wait_cb cmp_cb, const void *data, int timeout_millis) { struct timespec deadline = make_deadline(timeout_millis); SCOPED_MUTEX(lock, &sink->lock); /* wait for the start */ while (sink->num_messages < start + 1) { int r = ast_cond_timedwait(&sink->cond, &sink->lock, &deadline); if (r == ETIMEDOUT) { /* Timed out waiting for the start */ return -1; } if (r != 0) { ast_log(LOG_ERROR, "Unexpected condition error: %s\n", strerror(r)); return -2; } } while (!cmp_cb(sink->messages[start], data)) { ++start; while (sink->num_messages < start + 1) { int r = ast_cond_timedwait(&sink->cond, &sink->lock, &deadline); if (r == ETIMEDOUT) { return -1; } if (r != 0) { ast_log(LOG_ERROR, "Unexpected condition error: %s\n", strerror(r)); return -2; } } } return start; } struct stasis_message *stasis_test_message_create(void) { RAII_VAR(void *, data, NULL, ao2_cleanup); if (!stasis_test_message_type()) { return NULL; } /* We just need the unique pointer; don't care what's in it */ data = ao2_alloc(1, NULL); if (!data) { return NULL; } return stasis_message_create(stasis_test_message_type(), data); }