Beispiel #1
0
/**
 * Reads the previous key (order given by @a keycmp function).
 * @param[in] key
 * @param[in] tree
 * @param[out] data Entry value, can be @b NULL.
 * @return previous key or @b NULL if @a key is the first one.
 */
const void*
piojo_btree_prev(const void *key, const piojo_btree_t *tree, void **data)
{
        iter_t iter;
        PIOJO_ASSERT(tree);
        PIOJO_ASSERT(key);

        iter = search_node(key, tree);
        PIOJO_ASSERT(iter.bnode != NULL);

        if (! iter.bnode->leaf_p && iter.eidx < iter.bnode->ecnt + 1){
                iter.bnode = iter.bnode->children[iter.eidx];
                iter.eidx = iter.bnode->ecnt;
                search_max(&iter);
        }else if (iter.eidx > 0){
                --iter.eidx;
        }else{
                while (iter.bnode->parent != NULL){
                        iter.eidx = iter.bnode->pidx;
                        iter.bnode = iter.bnode->parent;
                        if (iter.eidx > 0){
                                --iter.eidx;
                                if (data != NULL){
                                        *data = entry_val(iter.eidx, iter.bnode, tree);
                                }
                                return entry_key(iter.eidx, iter.bnode, tree);
                        }
                }
                return NULL;
        }
        if (data != NULL){
                *data = entry_val(iter.eidx, iter.bnode, tree);
        }
        return entry_key(iter.eidx, iter.bnode, tree);
}
Beispiel #2
0
/**
 * Searches an entry by key.
 * @param[in] key Entry key.
 * @param[in] tree
 * @return Entry value or @b NULL if key doesn't exist.
 */
void*
piojo_btree_search(const void *key, const piojo_btree_t *tree)
{
        iter_t iter;
        PIOJO_ASSERT(tree);
        PIOJO_ASSERT(key);

        iter = search_node(key, tree);
        if (iter.bnode != NULL){
                return entry_val(iter.eidx, iter.bnode, tree);
        }
        return NULL;
}
Beispiel #3
0
void LogDefer::add_log(int verbosity, const std::string &msg) {
  picojson::array entry;
  struct timeval end_tv;

  gettimeofday(&end_tv, NULL);

  entry.push_back(time_delta(&end_tv, &start_tv_));
  entry.push_back(picojson::value((double)verbosity));
  entry.push_back(picojson::value(msg));

  picojson::value entry_val(entry);
  logs_.push_back(entry_val);
}
Beispiel #4
0
static void
init_entry(const void *key, const void *data, uint8_t eidx,
           const bnode_t *bnode, const piojo_btree_t *tree)
{
        bool null_p = TRUE;
        piojo_alloc_if ator = tree->allocator;

        if (data == NULL){
                data = &null_p;
        }

        memcpy(entry_key(eidx, bnode, tree), key, tree->eksize);

        bnode->kvs[eidx].value = ator.alloc_cb(tree->evsize);
        PIOJO_ASSERT(bnode->kvs[eidx].value);
        memcpy(entry_val(eidx, bnode, tree), data, tree->evsize);
}
Beispiel #5
0
/**
 * Reads the last key in @a tree (order given by @a keycmp function).
 * @param[in] tree
 * @param[out] data Entry value, can be @b NULL.
 * @return last key or @b NULL if @a tree is empty.
 */
const void*
piojo_btree_last(const piojo_btree_t *tree, void **data)
{
        iter_t iter;
        PIOJO_ASSERT(tree);

        if (tree->ecount > 0){
                iter.tree = tree;
                iter.eidx = tree->root->ecnt;
                iter.bnode = tree->root;
                search_max(&iter);
                if (data != NULL){
                        *data = entry_val(iter.eidx, iter.bnode, tree);
                }
                return entry_key(iter.eidx, iter.bnode, tree);
        }
        return NULL;
}
Beispiel #6
0
/**
 * Replaces or inserts an entry.
 * If @a data is @b NULL, the value is replaced with @b TRUE (useful for sets).
 * @param[in] key Entry key.
 * @param[in] data Entry value.
 * @param[out] tree Tree being modified.
 * @return @b TRUE if @a key is new, @b FALSE otherwise.
 */
bool
piojo_btree_set(const void *key, const void *data, piojo_btree_t *tree)
{
        iter_t iter;
        PIOJO_ASSERT(tree);
        PIOJO_ASSERT(key);
        PIOJO_ASSERT(data || tree->evsize == sizeof(bool));

        iter = insert_node(key, data, tree);
        if (iter.bnode == NULL){
                PIOJO_ASSERT(tree->ecount < SIZE_MAX);
                ++tree->ecount;
                return TRUE;
        }

        if (data != NULL){
                memcpy(entry_val(iter.eidx, iter.bnode, tree), data,
                       tree->evsize);
        }
        return FALSE;
}
Beispiel #7
0
int main(int ac, char **av)
{
	struct database *db;
	struct group *group = NULL;
	char *line = NULL;
	size_t linesz = 0;
	if (!av[1]) {
		printf("%s database\n", av[0]);
		exit(1);
	}
	printf("dbtest\n");
	db = open_db(av[1], 1);
	while (printf("> "),
		fflush(stdout),
		getline(&line, &linesz, stdin) > 0) {
		char *p = line + strlen(line) - 1;
		while (p >= line && isspace(*p))
			*p-- = 0;
		switch (line[0]) {
		case 's':
			C(sync_db(db));
			break;
		case 'q':
			C(close_db(db));
			exit(0);
		case 'g':
			group = find_group(db, line + 1);
			if (group)
				printf("found\n");
			break;
		case 'G':
			NEEDGROUP;
			C(delete_group(db, group));
			group = NULL;
			break;
		case 'a': {
			int existed = 0;
			group = add_group(db, line + 1, &existed);
			if (existed)
				printf("existed\n");
			break;
		}
		case 'v':
			NEEDGROUP;
			printf("%s\n", entry_val(group, line + 1));
			break;
		case 'c': {
			p = line + 1;
			char *entry = strsep(&p, ",");
			NEEDGROUP;
			change_entry(db, group, entry, strsep(&p, ""));
			break;
		}
		case 'L':
			NEEDGROUP;
			clone_group(db, group, line + 1);
			break;
		case 'f': {
			struct group *g;
			p = line + 1;
			char *entry = strsep(&p, ",");
			char *val = strsep(&p, "");
			g = NULL;
			int nr = 0;
			while ((g = find_entry(db, g, entry, val)) != NULL) {
				if (nr == 0)
					group = g;
				nr++;
				dump_group(group, stdout);
			}
			if (nr == 0)
				printf("not found\n");
			break;
		}
		case 'C':
			NEEDGROUP;
			add_comment(db, group, line + 1);
			break;
		case 'd':
			NEEDGROUP;
			dump_group(group, stdout);
			break;
		case 'D':
			dump_database(db, stdout);
			break;
		default:
			usage();
			break;
		}
	}
	return 0;
}