Exemplo n.º 1
0
static int add_member(rlite *db, rl_btree *scores, long scores_page, rl_skiplist *skiplist, long skiplist_page, double score, unsigned char *member, long memberlen)
{
	int retval;
	unsigned char *digest = NULL;
	void *value_ptr;
	RL_MALLOC(value_ptr, sizeof(double));
	digest = rl_malloc(sizeof(unsigned char) * 20);
	if (!digest) {
		rl_free(value_ptr);
		retval = RL_OUT_OF_MEMORY;
		goto cleanup;
	}
	*(double *)value_ptr = score;
	retval = sha1(member, memberlen, digest);
	if (retval != RL_OK) {
		rl_free(value_ptr);
		rl_free(digest);
		goto cleanup;
	}
	RL_CALL(rl_btree_add_element, RL_OK, db, scores, scores_page, digest, value_ptr);

	retval = rl_skiplist_add(db, skiplist, skiplist_page, score, member, memberlen);
	if (retval != RL_OK) {
		// This failure is critical. The btree already has the element, but
		// the skiplist failed to add it. If left as is, it would be in an
		// inconsistent state. Dropping all the transaction in progress.
		rl_discard(db);
		goto cleanup;
	}
cleanup:
	return retval;
}
Exemplo n.º 2
0
int rl_close(rlite *db)
{
	if (!db) {
		return RL_OK;
	}

	if (db->driver_type == RL_FILE_DRIVER) {
		rl_unsubscribe_all(db);
	}
	// discard before removing the driver, since we need to release locks
	rl_discard(db);
	if (db->driver_type == RL_FILE_DRIVER) {
		rl_file_driver *driver = db->driver;
		rl_free(driver->filename);
	}
	else if (db->driver_type == RL_MEMORY_DRIVER) {
		rl_memory_driver* driver = db->driver;
		rl_free(driver->data);
	}
	if (db->subscriber_lock_filename) {
		remove(db->subscriber_lock_filename);
		rl_free(db->subscriber_lock_filename);
	}
	rl_free(db->driver);
	rl_free(db->subscriber_id);
	rl_free(db->read_pages);
	rl_free(db->write_pages);
	rl_free(db->databases);
	rl_free(db->initial_databases);
	rl_free(db);
	return RL_OK;
}
Exemplo n.º 3
0
int rl_commit(struct rlite *db)
{
	int retval;
	RL_CALL(rl_write_apply_wal, RL_OK, db);
	db->initial_next_empty_page = db->next_empty_page;
	db->initial_number_of_pages = db->number_of_pages;
	db->initial_number_of_databases = db->number_of_databases;
	rl_free(db->initial_databases);
	RL_MALLOC(db->initial_databases, sizeof(long) * (db->number_of_databases + RLITE_INTERNAL_DB_COUNT));
	memcpy(db->initial_databases, db->databases, sizeof(long) * (db->number_of_databases + RLITE_INTERNAL_DB_COUNT));
	rl_discard(db);
cleanup:
	return retval;
}
Exemplo n.º 4
0
TEST btree_insert_oom()
{
	long btree_node_size = 2;
	rl_btree *btree = NULL;
	int retval;
	rlite *db = NULL;
	RL_CALL_VERBOSE(setup_db, RL_OK, &db, 0, 1);

	long *key;
	long *val;

	long j, i;
	int finished = 0;
	for (j = 1; !finished; j++) {
		for (i = 0; i < 7; i++) {
			test_mode = 0;
			RL_CALL_VERBOSE(rl_btree_create_size, RL_OK, db, &btree, &rl_btree_type_hash_long_long, btree_node_size);
			long btree_page = db->next_empty_page;
			RL_CALL_VERBOSE(rl_write, RL_OK, db, btree->type->btree_type, btree_page, btree);
			test_mode = 1;
			test_mode_caller = "rl_btree_add_element";
			test_mode_counter = j;
			key = malloc(sizeof(long));
			val = malloc(sizeof(long));
			*key = i + 1;
			*val = i * 10;
			CHECK_RETVAL(rl_btree_add_element(db, btree, btree_page, key, val));
			if (i == 6 && retval == RL_OK) {
				if (j == 1) {
					fprintf(stderr, "No OOM triggered\n");
					test_mode = 0;
					FAIL();
				}
				finished = 1;
				break;
			}
		}
		test_mode = 0;
		rl_discard(db);
	}
	test_mode = 0;
	rl_close(db);
	PASS();
}
Exemplo n.º 5
0
int rl_write(struct rlite *db, rl_data_type *type, long page_number, void *obj)
{
	// fprintf(stderr, "w %ld %s\n", page_number, type->name);
	rl_page *page = NULL;
	long pos;
	int retval;

	if (page_number == db->next_empty_page) {
		RL_CALL(rl_alloc_page_number, RL_OK, db, NULL);
		retval = rl_write(db, &rl_data_type_header, 0, NULL);
		if (retval != RL_OK) {
			goto cleanup;
		}
	}

	retval = rl_search_cache(db, type, page_number, NULL, &pos, NULL, db->write_pages, db->write_pages_len);
	if (retval == RL_FOUND) {
		if (obj != db->write_pages[pos]->obj) {
			if (db->write_pages[pos]->obj) {
				db->write_pages[pos]->type->destroy(db, db->write_pages[pos]->obj);
			}
			db->write_pages[pos]->obj = obj;
			db->write_pages[pos]->type = type;
		}
		retval = RL_OK;
	}
	else if (retval == RL_NOT_FOUND) {
		if (db->driver_type == RL_FILE_DRIVER) {
			RL_CALL(file_driver_fp, RL_OK, db);
		}
		rl_ensure_pages(db);
		RL_MALLOC(page, sizeof(*page));
#ifdef RL_DEBUG
		page->serialized_data = NULL;
#endif
		page->page_number = page_number;
		page->type = type;
		page->obj = obj;
		if (pos < db->write_pages_len) {
			memmove(&db->write_pages[pos + 1], &db->write_pages[pos], sizeof(rl_page *) * (db->write_pages_len - pos));
		}
		db->write_pages[pos] = page;
		db->write_pages_len++;

		retval = rl_search_cache(db, type, page_number, NULL, &pos, NULL, db->read_pages, db->read_pages_len);
		if (retval == RL_FOUND) {
#ifdef RL_DEBUG
			rl_free(db->read_pages[pos]->serialized_data);
#endif
			if (db->read_pages[pos]->obj != obj) {
				db->read_pages[pos]->type->destroy(db, db->read_pages[pos]->obj);
			}
			rl_free(db->read_pages[pos]);
			memmove(&db->read_pages[pos], &db->read_pages[pos + 1], sizeof(rl_page *) * (db->read_pages_len - pos));
			db->read_pages_len--;
			retval = RL_OK;
		}
		else if (retval != RL_NOT_FOUND) {
			goto cleanup;
		}
		retval = RL_OK;
	}

cleanup:
	if (retval != RL_OK) {
		if (obj) {
			type->destroy(db, obj);
			rl_purge_cache(db, page_number);
		}
		if (page_number != 0) {
			rl_discard(db);
		}
	}
	return retval;
}