コード例 #1
0
/*
 * Internal function: udf_aerospike_setbin
 *
 * Parameters:
 * 		r 		-- udf_record to be manipulated
 * 		bname 	-- name of the bin to be deleted
 *		val		-- value to be updated with
 *
 * Return value:
 * 		0  on success
 * 	   -1  on failure
 *
 * Description:
 * 		The function sets the bin with the name
 * 		passed in as parameter to the value, passed as the third parameter.
 * 		Before updating the bin, it is checked if the value can fit in the storage
 *
 * 		Synchronization : object lock acquired by the transaction thread executing UDF.
 * 		Partition reservation takes place just before the transaction starts executing
 * 		( look for as_partition_reserve_udf in thr_tsvc.c )
 *
 * 		Callers:
 * 		udf_aerospike__apply_update_atomic
 * 		In this function, if it fails at the time of update, the record is set
 * 		to rollback all the updates till this point. The case where it fails in
 * 		rollback is not handled.
 *
 * 		Side Notes:
 * 		i.	write_to_device will be set to true on a successful bin update.
 * 		If all the updates from udf_aerospike__apply_update_atomic (including this) are
 * 		successful, the record will be written to disk and reopened so that the rest of
 * 		sets of updates can be applied.
 *
 * 		ii.	If put in sindex fails, we do not handle it.
 *
 * 		TODO make sure anything goes into setbin only if the bin value is
 * 		          changed
 */
static const int
udf_aerospike_setbin(udf_record * urecord, const char * bname, const as_val * val, bool is_hidden)
{
	if (bname == NULL || bname[0] == 0 ) {
		cf_warning(AS_UDF, "no bin name supplied");
		return -1;
	}

	uint8_t type = as_val_type(val);
	if (is_hidden &&
			((type != AS_MAP) && (type != AS_LIST))) {
		cf_warning(AS_UDF, "Hidden %d Type Not allowed", type);
		return -3;
	}

	size_t          blen    = strlen(bname);
	as_storage_rd * rd      = urecord->rd;
	as_transaction *tr      = urecord->tr;
	as_index_ref  * index   = urecord->r_ref;

	as_bin * b = as_bin_get(rd, (byte *)bname, blen);

	if ( !b && (blen > (AS_ID_BIN_SZ - 1 )
				|| !as_bin_name_within_quota(rd->ns, (byte *)bname, blen)) ) {
		// Can't write bin
		cf_warning(AS_UDF, "bin name %s too big. Bin not added", bname);
		return -1;
	}
	if ( !b ) {
		// See if there's a free one, the hope is you will always find the bin because
		// you have already allocated bin space before calling this function.
		b = as_bin_create(index->r, rd, (byte *)bname, blen, 0);
		if (!b) {
			cf_warning(AS_UDF, "ERROR: udf_aerospike_setbin: as_bin_create: bin not found, something went really wrong!");
			return -1;
		}
	}

	SINDEX_BINS_SETUP(oldbin, 1);
	SINDEX_BINS_SETUP(newbin, 1);
	bool needs_sindex_delete = false;
	bool needs_sindex_put    = false;
	bool needs_sindex_update = false;
	bool has_sindex          = as_sindex_ns_has_sindex(rd->ns);

	if (has_sindex
			&& (as_sindex_sbin_from_bin(rd->ns,
					as_index_get_set_name(rd->r, rd->ns),
					b, oldbin) == AS_SINDEX_OK)) {
		needs_sindex_delete = true;
	}

	// we know we are doing an update now, make sure there is particle data,
	// set to be 1 wblock size now @TODO!
	uint32_t pbytes = 0;
	int ret = 0;
	if (!rd->ns->storage_data_in_memory && !urecord->particle_data) {
		urecord->particle_data = cf_malloc(rd->ns->storage_write_block_size);
		urecord->cur_particle_data = urecord->particle_data;
		urecord->end_particle_data = urecord->particle_data + rd->ns->storage_write_block_size;
	}

	cf_detail(AS_UDF, "udf_setbin: bin %s type %d ", bname, type );

	switch(type) {
		case AS_STRING: {
			as_string * v   = as_string_fromval(val);
			byte *      s   = (byte *) as_string_tostring(v);
			size_t      l   = as_string_len(v);

			// Save for later.
			// cf_detail(AS_UDF, "udf_setbin: string: binname %s value is %s",bname,s);

			if ( !as_storage_bin_can_fit(rd->ns, l) ) {
				cf_warning(AS_UDF, "string: bin size too big");
				ret = -1;
				break;
			}
			if (rd->ns->storage_data_in_memory) {
				as_particle_frombuf(b, AS_PARTICLE_TYPE_STRING, s, l, NULL, true);
			} else {
				pbytes = l + as_particle_get_base_size(AS_PARTICLE_TYPE_STRING);
				if ((urecord->cur_particle_data + pbytes) < urecord->end_particle_data) {
					as_particle_frombuf(b, AS_PARTICLE_TYPE_STRING, s, l,
										urecord->cur_particle_data,
										rd->ns->storage_data_in_memory);
					urecord->cur_particle_data += pbytes;
				} else {
					cf_warning(AS_UDF, "string: bin data size too big: pbytes %d"
								" pdata %p cur_part+pbytes %p pend %p", pbytes,
								urecord->particle_data, urecord->cur_particle_data + pbytes,
								urecord->end_particle_data);
					ret = -1;
					break;
				}
			}
			break;
		}
		case AS_BYTES: {
			as_bytes *  v   = as_bytes_fromval(val);
			uint8_t *   s   = as_bytes_get(v);
			size_t      l   = as_bytes_size(v);

			if ( !as_storage_bin_can_fit(rd->ns, l) ) {
				cf_warning(AS_UDF, "bytes: bin size too big");
				ret = -1;
				break;
			}
			if (rd->ns->storage_data_in_memory) {
				as_particle_frombuf(b, AS_PARTICLE_TYPE_BLOB, s, l, NULL, true);
			} else {
				pbytes = l + as_particle_get_base_size(AS_PARTICLE_TYPE_BLOB);
				if ((urecord->cur_particle_data + pbytes) < urecord->end_particle_data) {
					as_particle_frombuf(b, AS_PARTICLE_TYPE_BLOB, s, l, urecord->cur_particle_data,
										rd->ns->storage_data_in_memory);
					urecord->cur_particle_data += pbytes;
				} else {
					cf_warning(AS_UDF, "bytes: bin data size too big pbytes %d"
								" pdata %p cur_part+pbytes %p pend %p", pbytes,
								urecord->particle_data, urecord->cur_particle_data + pbytes,
								urecord->end_particle_data);
					ret = -1;
					break;
				}
			}
			break;
		}
		case AS_BOOLEAN: {
			as_boolean *    v   = as_boolean_fromval(val);
			bool            d   = as_boolean_get(v);
			int64_t         i   = __be64_to_cpup((void *)&d);

			if ( !as_storage_bin_can_fit(rd->ns, 8) ) {
				cf_warning(AS_UDF, "bool: bin size too big");
				ret = -1;
				break;
			}
			if (rd->ns->storage_data_in_memory) {
				as_particle_frombuf(b, AS_PARTICLE_TYPE_INTEGER, (uint8_t *) &i, 8, NULL, true);
			} else {
				pbytes = 8 + as_particle_get_base_size(AS_PARTICLE_TYPE_INTEGER);
				if ((urecord->cur_particle_data + pbytes) < urecord->end_particle_data) {
					as_particle_frombuf(b, AS_PARTICLE_TYPE_INTEGER,
										(uint8_t *) &i, 8,
										urecord->cur_particle_data,
										rd->ns->storage_data_in_memory);
					urecord->cur_particle_data += pbytes;
				} else {
					cf_warning(AS_UDF, "bool: bin data size too big: pbytes %d %p %p %p",
								pbytes, urecord->particle_data, urecord->cur_particle_data,
								urecord->end_particle_data);
					ret = -1;
					break;
				}
			}
			break;
		}
		case AS_INTEGER: {
			as_integer *    v   = as_integer_fromval(val);
			int64_t         i   = as_integer_get(v);
			int64_t         j   = __be64_to_cpup((void *)&i);

			if ( !as_storage_bin_can_fit(rd->ns, 8) ) {
				cf_warning(AS_UDF, "int: bin size too big");
				ret = -1;
				break;
			}
			if (rd->ns->storage_data_in_memory) {
				as_particle_frombuf(b, AS_PARTICLE_TYPE_INTEGER, (uint8_t *) &j, 8, NULL, true);
			} else {
				pbytes = 8 + as_particle_get_base_size(AS_PARTICLE_TYPE_INTEGER);
				if ((urecord->cur_particle_data + pbytes) < urecord->end_particle_data) {
					as_particle_frombuf(b, AS_PARTICLE_TYPE_INTEGER,
										(uint8_t *) &j, 8, urecord->cur_particle_data,
										rd->ns->storage_data_in_memory);
					urecord->cur_particle_data += pbytes;
				} else {
					cf_warning(AS_UDF, "int: bin data size too big: pbytes %d %p %p %p",
								pbytes, urecord->particle_data, urecord->cur_particle_data,
								urecord->end_particle_data);
					ret = -1;
					break;
				}
			}
			break;
		}
		// @LDT : Possibly include AS_LDT in this list.  We need the LDT
		// bins to be updated by LDT lua calls, and that path takes us thru here.
		// However, we ALSO need to be able to set the particle type for the
		// bins -- so that requires extra processing here to take the LDT flags
		// and set the appropriate bin flags in the particle data.
		case AS_MAP:
		case AS_LIST: {
			as_buffer buf;
			as_buffer_init(&buf);
			as_serializer s;
			as_msgpack_init(&s);
			int rsp = 0;
			as_serializer_serialize(&s, (as_val *) val, &buf);

			if ( !as_storage_bin_can_fit(rd->ns, buf.size) ) {
				cf_warning(AS_UDF, "map-list: bin size too big");
				ret = -1;
				// Clean Up and jump out.
				as_serializer_destroy(&s);
				as_buffer_destroy(&buf);
				break; // can't continue if value too big.
			}
			uint8_t ptype;
			if(is_hidden) {
				ptype = as_particle_type_convert_to_hidden(to_particle_type(type));
			} else {
				ptype = to_particle_type(type);
			}
			if (rd->ns->storage_data_in_memory) {
				as_particle_frombuf(b, ptype, (uint8_t *) buf.data, buf.size, NULL, true);
			}
			else {
				pbytes = buf.size + as_particle_get_base_size(ptype);
				if ((urecord->cur_particle_data + pbytes) < urecord->end_particle_data) {
					as_particle_frombuf(b, ptype, (uint8_t *) buf.data, buf.size,
										urecord->cur_particle_data,	rd->ns->storage_data_in_memory);
					urecord->cur_particle_data += pbytes;
				} else {
					cf_warning(AS_UDF, "map-list: bin data size too big: pbytes %d %p %p %p",
								pbytes, urecord->particle_data, urecord->cur_particle_data,
								urecord->end_particle_data);
					rsp = -1;
				}
			}
			as_serializer_destroy(&s);
			as_buffer_destroy(&buf);
			if (rsp) {
				ret = rsp;
				break;
			}
			break;
		}
		default: {
			cf_warning(AS_UDF, "unrecognized object type %d, skipping", as_val_type(val) );
			break;
		}

	}

	// If something fail bailout
	if (ret) {
		as_sindex_sbin_freeall(oldbin, 1);
		as_sindex_sbin_freeall(newbin, 1);
		return ret;
	}

	// Update sindex if required
	if (has_sindex) {
		if (as_sindex_sbin_from_bin(rd->ns,
				as_index_get_set_name(rd->r, rd->ns), b, newbin) == AS_SINDEX_OK) {
			if (!as_sindex_sbin_match(newbin, oldbin)) {
				needs_sindex_put    = true;
			} else {
				needs_sindex_update = true;
			}
		}

		if (needs_sindex_update) {
			tr->flag |= AS_TRANSACTION_FLAG_SINDEX_TOUCHED;
			as_sindex_delete_by_sbin(rd->ns,
					as_index_get_set_name(rd->r, rd->ns), 1, oldbin, rd);
			as_sindex_put_by_sbin(rd->ns,
					as_index_get_set_name(rd->r, rd->ns), 1, newbin, rd);
		} else {
			if (needs_sindex_delete) {
				tr->flag |= AS_TRANSACTION_FLAG_SINDEX_TOUCHED;
				as_sindex_delete_by_sbin(rd->ns,
					as_index_get_set_name(rd->r, rd->ns), 1, oldbin, rd);
			}
			if (needs_sindex_put) {
				tr->flag |= AS_TRANSACTION_FLAG_SINDEX_TOUCHED;
				as_sindex_put_by_sbin(rd->ns,
					as_index_get_set_name(rd->r, rd->ns), 1, newbin, rd);
			}
		}
		as_sindex_sbin_freeall(oldbin, 1);
		as_sindex_sbin_freeall(newbin, 1);
	}
	return ret;
} // end udf_aerospike_setbin()
コード例 #2
0
/**
 ********************************************************************************************************
 * Test existence of an object in the set.
 *
 * @param self                  AerospikeLSet object
 * @param args                  The args is a tuple object containing an argument
 *                              list passed from Python to a C function
 * @param kwds                  Dictionary of keywords
 * 
 * Returns true on success, Otherwise false is returned.
 * In case of error,appropriate exceptions will be raised.
 ********************************************************************************************************
 */
PyObject * AerospikeLSet_Exists(AerospikeLSet * self, PyObject * args, PyObject * kwds)
{
	PyObject * py_value = NULL;
	PyObject* py_policy = NULL;
	as_policy_apply apply_policy;
	as_policy_apply* apply_policy_p = NULL;
	as_val * val = NULL;

	as_static_pool static_pool;
	memset(&static_pool, 0, sizeof(static_pool));

	as_error err;
	as_error_init(&err);

	static char * kwlist[] = {"value", "policy", NULL};

	// Python Function Argument Parsing
	if ( PyArg_ParseTupleAndKeywords(args, kwds, "O|O:exists", kwlist, 
				&py_value, &py_policy) == false ) {
		return NULL;
	}

	if (!self || !self->client->as) {
		as_error_update(&err, AEROSPIKE_ERR_PARAM, "Invalid aerospike object");
		goto CLEANUP;
	}
	if (!self->client->is_conn_16) {
		as_error_update(&err, AEROSPIKE_ERR_CLUSTER, "No connection to aerospike cluster");
		goto CLEANUP;
	}

	// Convert python policy object to as_policy_apply
	pyobject_to_policy_apply(&err, py_policy, &apply_policy, &apply_policy_p,
			&self->client->as->config.policies.apply);
	if ( err.code != AEROSPIKE_OK ) {
		goto CLEANUP;
	}

	pyobject_to_val(&err, py_value, &val, &static_pool, SERIALIZER_PYTHON);
	if (err.code != AEROSPIKE_OK) {
		goto CLEANUP;
	}

	as_boolean exists;
	as_boolean_init(&exists, false);
	aerospike_lset_exists(self->client->as, &err, apply_policy_p, &self->key,
			&self->lset, val, &exists);
	if( err.code != AEROSPIKE_OK) {
		as_error_update(&err, err.code, NULL);
	}

CLEANUP:

	if (val) {
		as_val_destroy(val);
	}

	if ( err.code != AEROSPIKE_OK ) {
		PyObject * py_err = NULL, *py_key = NULL;
		PyObject *exception_type = raise_exception(&err);
		error_to_pyobject(&err, &py_err);
		if(PyObject_HasAttrString(exception_type, "key")) {
			key_to_pyobject(&err, &self->key, &py_key);
			PyObject_SetAttrString(exception_type, "key", py_key);
			Py_DECREF(py_key);
		} 
		if(PyObject_HasAttrString(exception_type, "bin")) {
			PyObject *py_bins = PyString_FromString((char *)&self->bin_name);
			PyObject_SetAttrString(exception_type, "bin", py_bins);
			Py_DECREF(py_bins);
		}
		PyErr_SetObject(exception_type, py_err);
		Py_DECREF(py_err);
		return NULL;
	}

	if (as_boolean_get(&exists))
		return Py_True;
	else
		return Py_False;
}
コード例 #3
0
ファイル: test.c プロジェクト: hugolu/aerospike-client-c
int
main(int argc, char* argv[])
{
	aerospike as;
	as_error err;
	as_boolean ldt_exists;
	as_ldt lstack, lstack2; 
	as_integer ival;
	as_string sval;
    as_bytes bval;
	uint32_t n_elements, cap_size;
	as_arraylist_iterator it;
	as_list* p_list = NULL;

	// Parse command line arguments.
	if (! example_get_opts(argc, argv, EXAMPLE_BASIC_OPTS)) {
		exit(-1);
	}

	// Connect to the aerospike database cluster.
	example_connect_to_aerospike(&as);

	// Start clean.
	example_remove_test_record(&as);

	// Create a large stack object to use. No need to destroy lstack if using
	// as_ldt_init() on stack object.
	as_ldt_init(&lstack, "mystack", AS_LDT_LSTACK, NULL);

	// Verify that the LDT is not already there.
	as_boolean_init(&ldt_exists, false);
	assert (aerospike_lstack_ldt_exists(&as, &err, NULL, &g_key, &lstack, &ldt_exists) == AEROSPIKE_OK);
	assert (as_boolean_get(&ldt_exists) == false);
	LOG("verified that lstack ldt is not present");

	// Push a few values onto the stack.
	// No need to destroy sval if using as_string_init() on stack object.

    // Push an integer
	as_integer_init(&ival, 123);
	assert (aerospike_lstack_push(&as, &err, NULL, &g_key, &lstack, (const as_val*)&ival) == AEROSPIKE_OK);

    // Push a string
	as_string_init(&sval, "string stack value", false);
	assert (aerospike_lstack_push(&as, &err, NULL, &g_key, &lstack, (const as_val*)&sval) == AEROSPIKE_OK);

    // Push bytes
    uint8_t buf[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
    as_bytes_init_wrap(&bval, buf, 16, false);
    assert (aerospike_lstack_push(&as, &err, NULL, &g_key, &lstack, (const as_val*)&bval) == AEROSPIKE_OK);


	// Look at the stack size right now.
	assert (aerospike_lstack_size(&as, &err, NULL, &g_key, &lstack, &n_elements) == AEROSPIKE_OK);
	LOG("%d values pushed", n_elements);

	// Peek a few values back.
	as_ldt_init(&lstack2, "mystack", AS_LDT_LSTACK, NULL);

	assert (aerospike_lstack_peek(&as, &err, NULL, &g_key, &lstack2, 3, &p_list) == AEROSPIKE_OK);

	// See if the elements match what we expect.
	as_arraylist_iterator_init(&it, (const as_arraylist*)p_list);
	while (as_arraylist_iterator_has_next(&it)) {
		const as_val* p_val = as_arraylist_iterator_next(&it);
		char* p_str = as_val_tostring(p_val);
		LOG("   peek - type = %d, value = %s", as_val_type(p_val), p_str);
		free(p_str);
	}
	as_list_destroy(p_list);
	p_list = NULL;

	// Push 3 more items onto the stack. By using as_arraylist_inita() we avoid
	// some but not all internal heap usage, so we must call
	// as_arraylist_destroy().
	as_arraylist vals;
	as_arraylist_inita(&vals, 3);
	as_arraylist_append_int64(&vals, 1000);
	as_arraylist_append_int64(&vals, 2000);
	as_arraylist_append_int64(&vals, 3000);

	assert (aerospike_lstack_push_all(&as, &err, NULL, &g_key, &lstack, (const as_list*)&vals) == AEROSPIKE_OK);
	as_arraylist_destroy(&vals);
	LOG("3 more values pushed");

	// Peek all the values back again.
	as_ldt_init(&lstack2, "mystack", AS_LDT_LSTACK, NULL);
	assert (aerospike_lstack_peek(&as, &err, NULL, &g_key, &lstack2, 10, &p_list) == AEROSPIKE_OK);

	// See if the elements match what we expect.
#if 0
	as_arraylist_iterator_init(&it, (const as_arraylist*)p_list);
	while (as_arraylist_iterator_has_next(&it)) {
		const as_val* p_val = as_arraylist_iterator_next(&it);
		char* p_str = as_val_tostring(p_val);

		LOG("   peek - type = %d, value = %s", as_val_type(p_val), p_str);
		free(p_str);
	}
#else
    const as_arraylist* p_array = (const as_arraylist*)p_list;
    int i;
    for (i = 0; i < p_array->size; i++) {
        const as_val* p_val = p_array->elements[i];
		char* p_str = as_val_tostring(p_val);
		LOG("   peek - type = %d, value = %s", as_val_type(p_val), p_str);
		free(p_str);
    }
#endif
	as_list_destroy(p_list);
    p_list = NULL;

	// Set capacity for the lstack.
	assert (aerospike_lstack_set_capacity(&as, &err, NULL, &g_key, &lstack, 10000) == AEROSPIKE_OK);

	// Get capacity from the lstack.
	assert (aerospike_lstack_get_capacity(&as, &err, NULL, &g_key, &lstack, &cap_size) == AEROSPIKE_OK);
	assert (cap_size == 10000);

	// Verify that the LDT is now present.
	as_boolean_init(&ldt_exists, false);
	assert (aerospike_lstack_ldt_exists(&as, &err, NULL, &g_key, &lstack, &ldt_exists) == AEROSPIKE_OK);
	assert (as_boolean_get(&ldt_exists) == true);
	LOG("verified that lstack ldt is present");

	// Destroy the lstack.
	assert (aerospike_lstack_destroy(&as, &err, NULL, &g_key, &lstack) == AEROSPIKE_OK);

	// See if we can still do any lstack operations.
	assert (aerospike_lstack_size(&as, &err, NULL, &g_key, &lstack, &n_elements) != AEROSPIKE_OK);

	// Cleanup and disconnect from the database cluster.
	example_cleanup(&as);
	LOG("lstack example successfully completed");

	return 0;
}
コード例 #4
0
ファイル: example.c プロジェクト: XeCycle/aerospike-client-c
int
main(int argc, char* argv[])
{
	// Parse command line arguments.
	if (! example_get_opts(argc, argv, EXAMPLE_BASIC_OPTS)) {
		exit(-1);
	}

	// Connect to the aerospike database cluster.
	aerospike as;
	example_connect_to_aerospike(&as);

	// Start clean.
	example_remove_test_record(&as);

	// Create a large map object to use. No need to destroy lmap if using
	// as_ldt_init() on stack object.
	as_ldt lmap;
	if (! as_ldt_init(&lmap, "mylmap", AS_LDT_LMAP, NULL)) {
		LOG("unable to initialize ldt");
		example_cleanup(&as);
		exit(-1);
	}

	as_error err;
	as_boolean ldt_exists;
	as_boolean_init(&ldt_exists, false);

	// Verify that the LDT is not already there.
	if (aerospike_lmap_ldt_exists(&as, &err, NULL, &g_key, &lmap,
			&ldt_exists) != AEROSPIKE_OK) {
		int rc = example_handle_udf_error(&err, "first aerospike_lmap_ldt_exists()");
		example_cleanup(&as);
		exit(rc);
	}

	if (as_boolean_get(&ldt_exists)) {
		LOG("found ldt that should not be present");
		example_cleanup(&as);
		exit(-1);
	}

	LOG("verified that lmap ldt is not present");

	// No need to destroy ikey if using as_integer_init() on stack object.
	as_integer ikey;
	as_integer_init(&ikey, 12345);

	// No need to destroy sval if using as_string_init() on stack object with
	// free parameter false.
	as_string sval;
	as_string_init(&sval, "lmap value", false);

	// Put a string entry to the lmap.
	if (aerospike_lmap_put(&as, &err, NULL, &g_key, &lmap,
			(const as_val*)&ikey, (as_val *)&sval) != AEROSPIKE_OK) {
		LOG("first aerospike_lmap_put() returned %d - %s", err.code,
				err.message);
		example_cleanup(&as);
		exit(-1);
	}

	// Ok to reuse.
	as_integer_init(&ikey, 345);

	as_integer ival;
	as_integer_init(&ival, 1000);

	// Put an integer entry to the lmap.
	if (aerospike_lmap_put(&as, &err, NULL, &g_key, &lmap,
			(const as_val*)&ikey, (as_val*)&ival) != AEROSPIKE_OK) {
		LOG("second aerospike_lmap_put() returned %d - %s", err.code,
				err.message);
		example_cleanup(&as);
		exit(-1);
	}

	LOG("2 entries added to map");

	uint32_t n_elements = 0;

	// See how many elements we have in the lmap now.
	if (aerospike_lmap_size(&as, &err, NULL, &g_key, &lmap, &n_elements) !=
			AEROSPIKE_OK) {
		LOG("aerospike_lmap_size() returned %d - %s", err.code, err.message);
		example_cleanup(&as);
		exit(-1);
	}

	if (n_elements != 2) {
		LOG("unexpected lmap size %u", n_elements);
		example_cleanup(&as);
		exit(-1);
	}

	LOG("lmap size confirmed to be %u", n_elements);

	as_boolean_init(&ldt_exists, false);

	// Verify that the LDT is now present.
	if (aerospike_lmap_ldt_exists(&as, &err, NULL, &g_key, &lmap,
			&ldt_exists) != AEROSPIKE_OK) {
		LOG("first aerospike_lmap_ldt_exists() returned %d - %s", err.code,
				err.message);
		example_cleanup(&as);
		exit(-1);
	}

	if (! as_boolean_get(&ldt_exists)) {
		LOG("did not find ldt that should be be present");
		example_cleanup(&as);
		exit(-1);
	}

	LOG("verified that lmap ldt is present");

	as_map* p_map = NULL;

	// Get all the entries back.
	if (aerospike_lmap_get_all(&as, &err, NULL, &g_key, &lmap, &p_map) !=
			AEROSPIKE_OK) {
		LOG("aerospike_lmap_filter() returned %d - %s", err.code, err.message);
		example_cleanup(&as);
		exit(-1);
	}

	as_hashmap_iterator it;
	as_hashmap_iterator_init(&it, (const as_hashmap*)p_map);

	// See if the elements match what we expect.
	while (as_hashmap_iterator_has_next(&it)) {
		const as_val* p_val = as_hashmap_iterator_next(&it);
		char* p_str = as_val_tostring(p_val);

		LOG("   element type %d, value %s", as_val_type(p_val), p_str);
		free(p_str);
	}

	as_map_destroy(p_map);
	p_map = NULL;

	as_integer_init(&ikey, 12345);

	// Remove an entry from the map.
	if (aerospike_lmap_remove(&as, &err, NULL, &g_key, &lmap,
			(const as_val*)&ikey) != AEROSPIKE_OK) {
		LOG("aerospike_lmap_remove() returned %d - %s", err.code, err.message);
		example_cleanup(&as);
		exit(-1);
	}

	as_val* p_val = NULL;

	// Make sure we can't get the value any more.
	as_status result = aerospike_lmap_get(&as, &err, NULL, &g_key, &lmap,
			(const as_val*)&ikey, &p_val);

	if (result == AEROSPIKE_OK) {
		// Server version >= 3.4.1 returns empty map if element doesn't exist.
		if (p_val && (as_val_type(p_val) != AS_MAP ||
				as_map_size((as_map*)p_val) != 0)) {
			char* p_str = as_val_tostring(p_val);

			LOG("entry was not successfully removed");
			LOG("   element type %d, value %s", as_val_type(p_val), p_str);
			free(p_str);

			as_val_destroy(p_val);
			example_cleanup(&as);
			exit(-1);
		}
	}
	else if (result != AEROSPIKE_ERR_LARGE_ITEM_NOT_FOUND) {
		LOG("aerospike_lmap_get() returned %d - %s", err.code, err.message);
		example_cleanup(&as);
		exit(-1);
	}

	LOG("entry successfully removed");

	// Destroy the lmap.
	if (aerospike_lmap_destroy(&as, &err, NULL, &g_key, &lmap) !=
			AEROSPIKE_OK) {
		LOG("aerospike_lmap_destroy() returned %d - %s", err.code, err.message);
		example_cleanup(&as);
		exit(-1);
	}

	n_elements = 0;

	// See if we can still do any lmap operations.
	if (aerospike_lmap_size(&as, &err, NULL, &g_key, &lmap, &n_elements) ==
			AEROSPIKE_OK) {
		LOG("aerospike_lmap_size() did not return error");
		example_cleanup(&as);
		exit(-1);
	}

	LOG("lmap successfully destroyed");

	// Cleanup and disconnect from the database cluster.
	example_cleanup(&as);

	LOG("lmap example successfully completed");

	return 0;
}
コード例 #5
0
#include "../test.h"

#include <aerospike/as_boolean.h>
#include <aerospike/as_buffer.h>
#include <aerospike/as_msgpack.h>
#include <aerospike/as_serializer.h>

/******************************************************************************
 * TEST CASES
 *****************************************************************************/

TEST( types_true, "as_true is true" ) {
	assert( as_boolean_get(&as_true) == true );
}

TEST( types_false, "as_false is false" ) {
	assert( as_boolean_get(&as_false) == false );
}

TEST( types_boolean_true, "as_boolean is true (init)" ) {
	as_boolean b;
	as_boolean_init(&b, true);
	assert( as_boolean_get(&b) == true );
	as_boolean_destroy(&b);
}

TEST( types_boolean_false, "as_boolean is false (init)" ) {
	as_boolean b;
	as_boolean_init(&b, false);
	assert( as_boolean_get(&b) == false );
	as_boolean_destroy(&b);