Example #1
0
/* 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;
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
/* 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);
}
Example #5
0
// 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;
}
Example #6
0
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;
}
Example #7
0
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);
}