Exemple #1
0
static int _zremiterator(rlite *db, const unsigned char *key, long keylen, long levels_page_number, rl_zset_iterator *iterator, rl_btree *scores, long scores_page, rl_skiplist *skiplist, long skiplist_page, long *changed)
{
	long _changed = 0;
	double score;
	unsigned char *member;
	long memberlen;
	int retval;
	while ((retval = rl_zset_iterator_next(iterator, &score, &member, &memberlen)) == RL_OK) {
		retval = remove_member_score(db, key, keylen, levels_page_number, scores, scores_page, skiplist, skiplist_page, member, memberlen, score);
		rl_free(member);
		if (retval != RL_OK && retval != RL_DELETED) {
			rl_zset_iterator_destroy(iterator);
			goto cleanup;
		}
		_changed++;
	}

	if (retval != RL_END) {
		goto cleanup;
	}

	*changed = _changed;
	retval = RL_OK;
cleanup:
	return retval;
}
Exemple #2
0
static int zunionstore_sum(rlite *db, long keys_size, unsigned char **keys, long *keys_len, double *weights)
{
	rl_skiplist_iterator *iterator = NULL;
	rl_skiplist *skiplist;
	double score;
	unsigned char *member;
	long memberlen;
	int retval;
	long i;
	for (i = 1; i < keys_size; i++) {
		retval = rl_zset_get_objects(db, keys[i], keys_len[i], NULL, NULL, NULL, &skiplist, NULL, 0, 0);
		if (retval == RL_NOT_FOUND) {
			continue;
		}
		if (retval != RL_OK) {
			goto cleanup;
		}
		RL_CALL(rl_skiplist_iterator_create, RL_OK, db, &iterator, skiplist, 0, 1, 0);
		while ((retval = rl_zset_iterator_next(iterator, &score, &member, &memberlen)) == RL_OK) {
			if (weights) {
				score *= weights[i - 1];
			}
			if (isnan(score)) {
				score = 0.0;
			}
			retval = incrby(db, keys[0], keys_len[0], score, member, memberlen, NULL, 1);
			rl_free(member);
			if (retval != RL_OK) {
				goto cleanup;
			}
		}
		iterator = NULL;

		if (retval != RL_END) {
			goto cleanup;
		}
	}

	retval = RL_OK;
cleanup:
	if (iterator) {
		rl_zset_iterator_destroy(iterator);
	}
	return retval;
}
Exemple #3
0
static int zunionstore_minmax(rlite *db, long keys_size, unsigned char **keys, long *keys_len, double *weights, int aggregate)
{
	rl_btree *target_scores;
	long target_scores_page, target_skiplist_page;
	rl_skiplist *target_skiplist;
	int retval;
	rl_skiplist_iterator **iterators = NULL;;
	rl_skiplist *skiplist;
	double *scores = NULL, score;
	unsigned char **members = NULL;
	long *memberslen = NULL, i;
	long position;
	RL_CALL(rl_zset_get_objects, RL_OK, db, keys[0], keys_len[0], NULL, &target_scores, &target_scores_page, &target_skiplist, &target_skiplist_page, 1, 1);
	RL_MALLOC(scores, sizeof(double) * keys_size);
	RL_MALLOC(members, sizeof(unsigned char *) * keys_size);
	for (i = 0; i < keys_size; i++) {
		members[i] = NULL;
	}
	RL_MALLOC(memberslen, sizeof(long) * keys_size);
	RL_MALLOC(iterators, sizeof(rl_skiplist_iterator *) * keys_size);
	for (i = 0; i < keys_size; i++) {
		iterators[i] = NULL;
	}

	for (i = 0; i < keys_size; i++) {
		retval = rl_zset_get_objects(db, keys[i], keys_len[i], NULL, NULL, NULL, &skiplist, NULL, 0, 0);
		if (retval == RL_NOT_FOUND) {
			iterators[i] = NULL;
			continue;
		}
		if (retval != RL_OK) {
			goto cleanup;
		}
		RL_CALL(rl_skiplist_iterator_create, RL_OK, db, &iterators[i], skiplist, 0, aggregate == RL_ZSET_AGGREGATE_MAX ? -1 : 1, 0);
		retval = rl_zset_iterator_next(iterators[i], &scores[i], &members[i], &memberslen[i]);
		if (retval != RL_OK) {
			iterators[i] = NULL;
			if (retval != RL_END) {
				goto cleanup;
			}
		}
	}

	while (1) {
		position = -1;
		for (i = 0; i < keys_size; i++) {
			if (!iterators[i]) {
				continue;
			}
			if (position == -1) {
				position = i;
				continue;
			}
			score = weights ? weights[position - 1] * scores[position] : scores[position];
			if (isnan(score)) {
				score = 0.0;
			}
			if ((aggregate == RL_ZSET_AGGREGATE_MAX && scores[i] > score) ||
			        (aggregate == RL_ZSET_AGGREGATE_MIN && scores[i] < score)) {
				position = i;
			}
		}
		if (position == -1) {
			break;
		}

		score = weights ? weights[position - 1] * scores[position] : scores[position];
		if (isnan(score)) {
			score = 0.0;
		}
		retval = add_member(db, target_scores, target_scores_page, target_skiplist, target_skiplist_page, score, members[position], memberslen[position]);
		if (retval != RL_FOUND && retval != RL_OK) {
			goto cleanup;
		}
		rl_free(members[position]);
		members[position] = NULL;

		retval = rl_zset_iterator_next(iterators[position], &scores[position], &members[position], &memberslen[position]);
		if (retval != RL_OK) {
			iterators[position] = NULL;
			if (retval != RL_END) {
				goto cleanup;
			}
		}
	}
	if (target_scores->number_of_elements == 0) {
		RL_CALL(rl_key_delete_with_value, RL_OK, db, keys[0], keys_len[0]);
	}

	retval = RL_OK;
cleanup:
	if (iterators) {
		for (i = 0; i < keys_size; i++) {
			if (iterators[i]) {
				rl_zset_iterator_destroy(iterators[i]);
			}
			rl_free(members[i]);
		}
	}
	rl_free(iterators);
	rl_free(memberslen);
	rl_free(members);
	rl_free(scores);
	return retval;
}
Exemple #4
0
int rl_dump(struct rlite *db, const unsigned char *key, long keylen, unsigned char **data, long *datalen)
{
	int retval;
	uint64_t crc;
	unsigned char type;
	unsigned char *value = NULL, *value2 = NULL;
	unsigned char *buf = NULL;
	long buflen;
	long valuelen, value2len;
	unsigned char **values = NULL;
	long i = -1, *valueslen = NULL;
	uint32_t length;
	double score;
	char f[40];

	RL_CALL(rl_key_get, RL_FOUND, db, key, keylen, &type, NULL, NULL, NULL, NULL);
	if (type == RL_TYPE_STRING) {
		RL_CALL(rl_get, RL_OK, db, key, keylen, &value, &valuelen);
		RL_MALLOC(buf, sizeof(unsigned char) * (16 + valuelen));
		buf[0] = REDIS_RDB_TYPE_STRING;
		buf[1] = (REDIS_RDB_32BITLEN << 6);
		length = htonl(valuelen);
		memcpy(&buf[2], &length, 4);
		memcpy(&buf[6], value, valuelen);
		buflen = valuelen + 6;
	} else if (type == RL_TYPE_LIST) {
		RL_CALL(rl_lrange, RL_OK, db, key, keylen, 0, -1, &valuelen, &values, &valueslen);
		buflen = 16;
		for (i = 0; i < valuelen; i++) {
			buflen += 5 + valueslen[i];
		}
		RL_MALLOC(buf, sizeof(unsigned char) * buflen);
		buf[0] = REDIS_RDB_TYPE_LIST;
		buf[1] = (REDIS_RDB_32BITLEN << 6);
		length = htonl(valuelen);
		memcpy(&buf[2], &length, 4);
		buflen = 6;
		for (i = 0; i < valuelen; i++) {
			buf[buflen++] = (REDIS_RDB_32BITLEN << 6);
			length = htonl(valueslen[i]);
			memcpy(&buf[buflen], &length, 4);
			buflen += 4;
			memcpy(&buf[buflen], values[i], valueslen[i]);
			buflen += valueslen[i];
		}
	} else if (type == RL_TYPE_SET) {
		rl_set_iterator *iterator;
		RL_CALL(rl_smembers, RL_OK, db, &iterator, key, keylen);
		buflen = 16;
		length = 0;
		while ((retval = rl_set_iterator_next(iterator, NULL, &valuelen)) == RL_OK) {
			buflen += 5 + valuelen;
			length++;
		}
		if (retval != RL_END) {
			goto cleanup;
		}

		RL_MALLOC(buf, sizeof(unsigned char) * buflen);
		buf[0] = REDIS_RDB_TYPE_SET;
		buf[1] = (REDIS_RDB_32BITLEN << 6);
		length = htonl(length);
		memcpy(&buf[2], &length, 4);
		buflen = 6;

		RL_CALL(rl_smembers, RL_OK, db, &iterator, key, keylen);
		while ((retval = rl_set_iterator_next(iterator, &value, &valuelen)) == RL_OK) {
			buf[buflen++] = (REDIS_RDB_32BITLEN << 6);
			length = htonl(valuelen);
			memcpy(&buf[buflen], &length, 4);
			buflen += 4;
			memcpy(&buf[buflen], value, valuelen);
			buflen += valuelen;
			rl_free(value);
			value = NULL;
		}
		if (retval != RL_END) {
			goto cleanup;
		}
	} else if (type == RL_TYPE_ZSET) {
		rl_zset_iterator *iterator;
		RL_CALL(rl_zrange, RL_OK, db, key, keylen, 0, -1, &iterator);
		buflen = 16;
		length = 0;
		while ((retval = rl_zset_iterator_next(iterator, &score, NULL, &valuelen)) == RL_OK) {
			buflen += 6 + valuelen + snprintf(f, 40, "%lf", score);
			length++;
		}
		if (retval != RL_END) {
			goto cleanup;
		}

		RL_MALLOC(buf, sizeof(unsigned char) * buflen);
		buf[0] = REDIS_RDB_TYPE_ZSET;
		buf[1] = (REDIS_RDB_32BITLEN << 6);
		length = htonl(length);
		memcpy(&buf[2], &length, 4);
		buflen = 6;

		RL_CALL(rl_zrange, RL_OK, db, key, keylen, 0, -1, &iterator);
		while ((retval = rl_zset_iterator_next(iterator, &score, &value, &valuelen)) == RL_OK) {
			buf[buflen++] = (REDIS_RDB_32BITLEN << 6);
			length = htonl(valuelen);
			memcpy(&buf[buflen], &length, 4);
			buflen += 4;
			memcpy(&buf[buflen], value, valuelen);
			buflen += valuelen;
			rl_free(value);
			value = NULL;

			valuelen = snprintf(f, 40, "%lf", score);
			buf[buflen++] = valuelen;
			memcpy(&buf[buflen], f, valuelen);
			buflen += valuelen;
		}
		if (retval != RL_END) {
			goto cleanup;
		}
	} else if (type == RL_TYPE_HASH) {
		rl_hash_iterator *iterator;
		RL_CALL(rl_hgetall, RL_OK, db, &iterator, key, keylen);
		buflen = 16;
		length = 0;
		while ((retval = rl_hash_iterator_next(iterator, NULL, &value2len, NULL, &valuelen)) == RL_OK) {
			buflen += 10 + valuelen + value2len;
			length++;
		}
		if (retval != RL_END) {
			goto cleanup;
		}

		RL_MALLOC(buf, sizeof(unsigned char) * buflen);
		buf[0] = REDIS_RDB_TYPE_HASH;
		buf[1] = (REDIS_RDB_32BITLEN << 6);
		length = htonl(length);
		memcpy(&buf[2], &length, 4);
		buflen = 6;

		RL_CALL(rl_hgetall, RL_OK, db, &iterator, key, keylen);
		while ((retval = rl_hash_iterator_next(iterator, &value, &valuelen, &value2, &value2len)) == RL_OK) {
			buf[buflen++] = (REDIS_RDB_32BITLEN << 6);
			length = htonl(valuelen);
			memcpy(&buf[buflen], &length, 4);
			buflen += 4;
			memcpy(&buf[buflen], value, valuelen);
			buflen += valuelen;
			rl_free(value);
			value = NULL;

			buf[buflen++] = (REDIS_RDB_32BITLEN << 6);
			length = htonl(value2len);
			memcpy(&buf[buflen], &length, 4);
			buflen += 4;
			memcpy(&buf[buflen], value2, value2len);
			buflen += value2len;
			rl_free(value2);
			value2 = NULL;
		}
	} else {
		retval = RL_UNEXPECTED;
		goto cleanup;
	}
	buf[buflen++] = REDIS_RDB_VERSION;
	buf[buflen++] = REDIS_RDB_VERSION >> 8;

	crc = rl_crc64(0, buf, buflen);
	memrev64ifbe(&crc);
	memcpy(&buf[buflen], &crc, 8);
	buflen += 8;

	*data = buf;
	*datalen = buflen;
	retval = RL_OK;
cleanup:
	if (values) {
		for (i = 0; i < valuelen; i++) {
			rl_free(values[i]);
		}
		rl_free(values);
	}
	rl_free(valueslen);
	rl_free(value);
	rl_free(value2);
	return retval;
}