bool user_callback_wrapper(const as_val *val, void *udata) {
	zval retval;
	ZVAL_NULL(&retval);
	if (!val) {
		return false;
	}
	as_record* record = as_record_fromval(val);
	user_callback_function* callback_info = (user_callback_function*)udata;

	pthread_mutex_lock(callback_info->cb_mutex);
	callback_info->callback.retval = &retval;

	if (execute_user_callback(record, callback_info) != AEROSPIKE_OK) {
		as_error_update(callback_info->err, AEROSPIKE_ERR_PARAM, "Callback raised an error");
		pthread_mutex_unlock(callback_info->cb_mutex);
		return false;
	}

	if (callback_info->callback.retval &&
			Z_TYPE_P(callback_info->callback.retval) == IS_FALSE) {
		pthread_mutex_unlock(callback_info->cb_mutex);
		return false;
	}

	zval_dtor(&retval);
	pthread_mutex_unlock(callback_info->cb_mutex);
	return true;
}
Пример #2
0
bool
scan_cb(const as_val* p_val, void* udata)
{
	if (! p_val) {
		LOG("scan callback returned null - scan is complete");
		return true;
	}

	// The scan didn't use a UDF, so the as_val object should be an as_record.
	as_record* p_rec = as_record_fromval(p_val);

	if (! p_rec) {
		LOG("scan callback returned non-as_record object");
		return true;
	}

	LOG("scan callback returned record:");
	example_dump_record(p_rec);

	return true;
}
Пример #3
0
static bool scan_check_callback(const as_val * val, void * udata) 
{
	int i;

	// NULL is END OF SCAN
	if ( !val ) {
		return false;
	}
	
	scan_check * check = (scan_check *) udata;

	as_record * rec = as_record_fromval(val);
	if ( !rec ) {
		error("Expected a record, but got type %d", as_val_type(val));
		return !(check->failed = true);
	}

	const char * set = rec->key.set[0] == '\0' ? NULL : rec->key.set;

	check->count++;
	// Find the number of unique threads spawned under the hood.
	// Note that the scan callback will be called in the thread context.
	// As the number of threads is same as node count, they will be limited.
	// A linear search is good enough for this.
	pthread_t cur_thread = pthread_self();
	for (i=0; i<check->unique_tcount; i++) {
		if (check->threadids[i] == cur_thread) {
			break;
		}
	}
	// Found a new thread
	if (i == check->unique_tcount) {
		check->threadids[check->unique_tcount] = cur_thread;
		check->unique_tcount++;
	}

	// Check if we are getting the results only from the set the scan is triggered for
	// If scan is called with NULL set, all the recs will come. So, no checks in this case.
	if ( check->set ) {
		// Do the check only if the rec also have a setname
		if ( !set ) {
			error("Expected set '%s', but got set NULL", check->set);
			return !(check->failed = true);
		}
		else if ( strcmp(check->set, set) != 0) {
			error("Expected set '%s', but got set '%s'", check->set, set);
			return !(check->failed = true);
		}
	}

	// Check that we got the right number of bins
	int numbins = as_record_numbins(rec);

	if ( check->nobindata ) {
		if ( numbins != 0 ) {
			error("Expected 0 bins, but got %d", numbins);
			return !(check->failed = true);
		}
		return !(check->failed = false);
	} 

	// only validate data if in sb_set1 or sb_set2
	if ( check->set && strcmp(set, SET1) != 0 && strcmp(set, SET2) != 0 ) {
		return !(check->failed = false);
	}

	// validate bins
	int nbins = sizeof(check->bins) / sizeof(char *);
	for( int i = 0; check->bins[i] && i < nbins; i++ ) {
		char * bin = check->bins[i];
		if ( strcmp(bin, "bin1") == 0 ) {
			if ( !check_bin1(rec, check) ) {
				error("Failed check of bin1");
				return !(check->failed = true);
			}
		}
		else if ( strcmp(bin, "bin2") == 0 ) {
			if ( !check_bin2(rec, check) ) {
				error("Failed check of bin2");
				return !(check->failed = true);
			}
		}
		else if ( strcmp(bin, "bin3") == 0 ) {
			if ( !check_bin3(rec, check) ) {
				error("Failed check of bin3");
				return !(check->failed = true);
			}
		}
		else if ( strcmp(bin, "bin4") == 0 ) {
			if ( !check_bin4(rec, check) ) {
				error("Failed check of bin4");
				return !(check->failed = true);
			}
		}
		else {
			error("Unknown bin %s", bin);
			return !(check->failed = true);
		}
	}

	return !(check->failed = false);
}