mirror of
https://github.com/libretro/RetroArch
synced 2025-02-03 17:54:04 +00:00
(libretroDB) Style nits
This commit is contained in:
parent
66641d7828
commit
b5040ef3dc
@ -35,8 +35,9 @@
|
|||||||
int rl_fnmatch(const char *pattern, const char *string, int flags)
|
int rl_fnmatch(const char *pattern, const char *string, int flags)
|
||||||
{
|
{
|
||||||
const char *c;
|
const char *c;
|
||||||
int charmatch = 0;
|
|
||||||
int rv;
|
int rv;
|
||||||
|
int charmatch = 0;
|
||||||
|
|
||||||
for (c = pattern; *c != '\0'; c++)
|
for (c = pattern; *c != '\0'; c++)
|
||||||
{
|
{
|
||||||
/* String ended before pattern */
|
/* String ended before pattern */
|
||||||
|
@ -23,7 +23,8 @@ static char *strndup_(const char *s, size_t n)
|
|||||||
return buff;
|
return buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct rmsgpack_dom_value *get_map_value(const struct rmsgpack_dom_value *m, char* key)
|
static struct rmsgpack_dom_value *get_map_value(
|
||||||
|
const struct rmsgpack_dom_value *m, char* key)
|
||||||
{
|
{
|
||||||
struct rmsgpack_dom_value v;
|
struct rmsgpack_dom_value v;
|
||||||
|
|
||||||
@ -261,10 +262,12 @@ int main(int argc, char **argv)
|
|||||||
int rv = 0;
|
int rv = 0;
|
||||||
int src = -1;
|
int src = -1;
|
||||||
int dst = -1;
|
int dst = -1;
|
||||||
|
|
||||||
if (argc != 3)
|
if (argc != 3)
|
||||||
printf("Usage: %s <dat file> <output file>\n", argv[0]);
|
printf("Usage: %s <dat file> <output file>\n", argv[0]);
|
||||||
|
|
||||||
src = open(argv[1], O_RDONLY);
|
src = open(argv[1], O_RDONLY);
|
||||||
|
|
||||||
if (src == -1)
|
if (src == -1)
|
||||||
{
|
{
|
||||||
printf("Could not open source file '%s': %s\n", argv[1], strerror(errno));
|
printf("Could not open source file '%s': %s\n", argv[1], strerror(errno));
|
||||||
@ -273,6 +276,7 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dst = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
|
dst = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
|
||||||
|
|
||||||
if (dst == -1)
|
if (dst == -1)
|
||||||
{
|
{
|
||||||
printf("Could not open destination file '%s': %s\n", argv[1], strerror(errno));
|
printf("Could not open destination file '%s': %s\n", argv[1], strerror(errno));
|
||||||
|
@ -20,124 +20,115 @@
|
|||||||
#include "libretrodb_endian.h"
|
#include "libretrodb_endian.h"
|
||||||
#include "query.h"
|
#include "query.h"
|
||||||
|
|
||||||
struct node_iter_ctx {
|
struct node_iter_ctx
|
||||||
|
{
|
||||||
libretrodb_t *db;
|
libretrodb_t *db;
|
||||||
libretrodb_index_t *idx;
|
libretrodb_index_t *idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct rmsgpack_dom_value sentinal;
|
static struct rmsgpack_dom_value sentinal;
|
||||||
|
|
||||||
static int libretrodb_read_metadata(
|
static int libretrodb_read_metadata(int fd, libretrodb_metadata_t *md)
|
||||||
int fd,
|
{
|
||||||
libretrodb_metadata_t *md
|
return rmsgpack_dom_read_into(fd, "count", &md->count, NULL);
|
||||||
){
|
|
||||||
return rmsgpack_dom_read_into(fd, "count", &md->count, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int libretrodb_write_metadata(
|
static int libretrodb_write_metadata(int fd, libretrodb_metadata_t *md)
|
||||||
int fd,
|
{
|
||||||
libretrodb_metadata_t *md
|
rmsgpack_write_map_header(fd, 1);
|
||||||
){
|
rmsgpack_write_string(fd, "count", strlen("count"));
|
||||||
rmsgpack_write_map_header(fd, 1);
|
return rmsgpack_write_uint(fd, md->count);
|
||||||
rmsgpack_write_string(fd, "count", strlen("count"));
|
|
||||||
return rmsgpack_write_uint(fd, md->count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int validate_document(const struct rmsgpack_dom_value * doc) {
|
static int validate_document(const struct rmsgpack_dom_value * doc)
|
||||||
int rv = 0;
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
struct rmsgpack_dom_value key;
|
struct rmsgpack_dom_value key;
|
||||||
struct rmsgpack_dom_value value;
|
struct rmsgpack_dom_value value;
|
||||||
|
int rv = 0;
|
||||||
|
|
||||||
if (doc->type != RDT_MAP) {
|
if (doc->type != RDT_MAP)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < doc->map.len; i++) {
|
for (i = 0; i < doc->map.len; i++)
|
||||||
key = doc->map.items[i].key;
|
{
|
||||||
value = doc->map.items[i].value;
|
key = doc->map.items[i].key;
|
||||||
if (key.type != RDT_STRING) {
|
value = doc->map.items[i].value;
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (key.string.len <= 0) {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (key.string.buff[0] == '$') {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value.type == RDT_MAP) {
|
if (key.type != RDT_STRING)
|
||||||
if ((rv == validate_document(&value)) != 0) {
|
return -EINVAL;
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
if (key.string.len <= 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (key.string.buff[0] == '$')
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (value.type != RDT_MAP)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((rv == validate_document(&value)) != 0)
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
int libretrodb_create(
|
int libretrodb_create(int fd, libretrodb_value_provider value_provider,
|
||||||
int fd,
|
void * ctx)
|
||||||
libretrodb_value_provider value_provider,
|
{
|
||||||
void * ctx
|
int rv;
|
||||||
){
|
off_t root;
|
||||||
int rv;
|
libretrodb_metadata_t md;
|
||||||
off_t root;
|
uint64_t item_count = 0;
|
||||||
libretrodb_metadata_t md;
|
struct rmsgpack_dom_value item = {};
|
||||||
uint64_t item_count = 0;
|
libretrodb_header_t header = {};
|
||||||
struct rmsgpack_dom_value item = {};
|
|
||||||
libretrodb_header_t header = {};
|
|
||||||
|
|
||||||
memcpy(header.magic_number, MAGIC_NUMBER, sizeof(MAGIC_NUMBER)-1);
|
memcpy(header.magic_number, MAGIC_NUMBER, sizeof(MAGIC_NUMBER)-1);
|
||||||
root = lseek(fd, 0, SEEK_CUR);
|
root = lseek(fd, 0, SEEK_CUR);
|
||||||
|
|
||||||
/* We write the header in the end because we need to know the size of
|
/* We write the header in the end because we need to know the size of
|
||||||
* the db first */
|
* the db first */
|
||||||
|
|
||||||
lseek(fd, sizeof(libretrodb_header_t), SEEK_CUR);
|
lseek(fd, sizeof(libretrodb_header_t), SEEK_CUR);
|
||||||
|
|
||||||
while ((rv = value_provider(ctx, &item)) == 0) {
|
while ((rv = value_provider(ctx, &item)) == 0)
|
||||||
|
{
|
||||||
|
if ((rv = validate_document(&item)) < 0)
|
||||||
|
goto clean;
|
||||||
|
|
||||||
if ((rv = validate_document(&item)) < 0)
|
if ((rv = rmsgpack_dom_write(fd, &item)) < 0)
|
||||||
goto clean;
|
goto clean;
|
||||||
|
|
||||||
if ((rv = rmsgpack_dom_write(fd, &item)) < 0)
|
item_count++;
|
||||||
goto clean;
|
}
|
||||||
|
|
||||||
item_count++;
|
if (rv < 0)
|
||||||
}
|
goto clean;
|
||||||
|
|
||||||
if (rv < 0)
|
if ((rv = rmsgpack_dom_write(fd, &sentinal)) < 0)
|
||||||
goto clean;
|
goto clean;
|
||||||
|
|
||||||
if ((rv = rmsgpack_dom_write(fd, &sentinal)) < 0)
|
header.metadata_offset = httobe64(lseek(fd, 0, SEEK_CUR));
|
||||||
goto clean;
|
md.count = item_count;
|
||||||
|
libretrodb_write_metadata(fd, &md);
|
||||||
header.metadata_offset = httobe64(lseek(fd, 0, SEEK_CUR));
|
lseek(fd, root, SEEK_SET);
|
||||||
md.count = item_count;
|
write(fd, &header, sizeof(header));
|
||||||
libretrodb_write_metadata(fd, &md);
|
|
||||||
lseek(fd, root, SEEK_SET);
|
|
||||||
write(fd, &header, sizeof(header));
|
|
||||||
clean:
|
clean:
|
||||||
rmsgpack_dom_value_free(&item);
|
rmsgpack_dom_value_free(&item);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int libretrodb_read_index_header(
|
static int libretrodb_read_index_header(int fd, libretrodb_index_t *idx)
|
||||||
int fd, libretrodb_index_t *idx)
|
|
||||||
{
|
{
|
||||||
uint64_t name_len = 50;
|
uint64_t name_len = 50;
|
||||||
return rmsgpack_dom_read_into(
|
return rmsgpack_dom_read_into(fd,
|
||||||
fd,
|
"name", idx->name, &name_len,
|
||||||
"name", idx->name, &name_len,
|
"key_size", &idx->key_size,
|
||||||
"key_size", &idx->key_size,
|
"next", &idx->next, NULL);
|
||||||
"next", &idx->next,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void libretrodb_write_index_header(
|
static void libretrodb_write_index_header(int fd, libretrodb_index_t * idx)
|
||||||
int fd, libretrodb_index_t * idx)
|
|
||||||
{
|
{
|
||||||
rmsgpack_write_map_header(fd, 3);
|
rmsgpack_write_map_header(fd, 3);
|
||||||
rmsgpack_write_string(fd, "name", strlen("name"));
|
rmsgpack_write_string(fd, "name", strlen("name"));
|
||||||
@ -154,54 +145,55 @@ void libretrodb_close(libretrodb_t * db)
|
|||||||
db->fd = -1;
|
db->fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int libretrodb_open(
|
int libretrodb_open(const char * path, libretrodb_t * db)
|
||||||
const char * path,
|
|
||||||
libretrodb_t * db
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
libretrodb_header_t header;
|
libretrodb_header_t header;
|
||||||
libretrodb_metadata_t md;
|
libretrodb_metadata_t md;
|
||||||
int rv;
|
int rv;
|
||||||
int fd = open(path, O_RDWR);
|
int fd = open(path, O_RDWR);
|
||||||
|
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
db->root = lseek(fd, 0, SEEK_CUR);
|
db->root = lseek(fd, 0, SEEK_CUR);
|
||||||
if ((rv = read(fd, &header, sizeof(header))) == -1) {
|
|
||||||
rv = -errno;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strncmp(header.magic_number, MAGIC_NUMBER, sizeof(MAGIC_NUMBER)) != 0) {
|
if ((rv = read(fd, &header, sizeof(header))) == -1)
|
||||||
rv = -EINVAL;
|
{
|
||||||
goto error;
|
rv = -errno;
|
||||||
}
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
header.metadata_offset = betoht64(header.metadata_offset);
|
if (strncmp(header.magic_number, MAGIC_NUMBER, sizeof(MAGIC_NUMBER)) != 0)
|
||||||
lseek(fd, header.metadata_offset, SEEK_SET);
|
{
|
||||||
if (libretrodb_read_metadata(fd, &md) < 0) {
|
rv = -EINVAL;
|
||||||
rv = -EINVAL;
|
goto error;
|
||||||
goto error;
|
}
|
||||||
}
|
|
||||||
db->count = md.count;
|
header.metadata_offset = betoht64(header.metadata_offset);
|
||||||
db->first_index_offset = lseek(fd, 0, SEEK_CUR);
|
lseek(fd, header.metadata_offset, SEEK_SET);
|
||||||
db->fd = fd;
|
|
||||||
return 0;
|
if (libretrodb_read_metadata(fd, &md) < 0)
|
||||||
|
{
|
||||||
|
rv = -EINVAL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
db->count = md.count;
|
||||||
|
db->first_index_offset = lseek(fd, 0, SEEK_CUR);
|
||||||
|
db->fd = fd;
|
||||||
|
return 0;
|
||||||
error:
|
error:
|
||||||
close(fd);
|
close(fd);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int libretrodb_find_index(
|
static int libretrodb_find_index(libretrodb_t *db, const char *index_name,
|
||||||
libretrodb_t *db,
|
libretrodb_index_t *idx)
|
||||||
const char *index_name,
|
{
|
||||||
libretrodb_index_t *idx
|
off_t eof = lseek(db->fd, 0, SEEK_END);
|
||||||
){
|
off_t offset = lseek(db->fd, db->first_index_offset, SEEK_SET);
|
||||||
off_t eof = lseek(db->fd, 0, SEEK_END);
|
|
||||||
off_t offset = lseek(db->fd, db->first_index_offset, SEEK_SET);
|
|
||||||
|
|
||||||
while (offset < eof)
|
while (offset < eof)
|
||||||
{
|
{
|
||||||
libretrodb_read_index_header(db->fd, idx);
|
libretrodb_read_index_header(db->fd, idx);
|
||||||
if (strncmp(index_name, idx->name, strlen(idx->name)) == 0)
|
if (strncmp(index_name, idx->name, strlen(idx->name)) == 0)
|
||||||
@ -209,83 +201,79 @@ static int libretrodb_find_index(
|
|||||||
offset = lseek(db->fd, idx->next, SEEK_CUR);
|
offset = lseek(db->fd, idx->next, SEEK_CUR);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int node_compare(
|
static int node_compare(const void * a, const void * b, void * ctx)
|
||||||
const void * a,
|
{
|
||||||
const void * b,
|
return memcmp(a, b, *(uint8_t *)ctx);
|
||||||
void * ctx
|
|
||||||
){
|
|
||||||
return memcmp(a, b, *(uint8_t *)ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int binsearch(
|
static int binsearch(const void * buff, const void * item,
|
||||||
const void * buff,
|
uint64_t count, uint8_t field_size, uint64_t * offset)
|
||||||
const void * item,
|
{
|
||||||
uint64_t count,
|
int mid = count / 2;
|
||||||
uint8_t field_size,
|
int item_size = field_size + sizeof(uint64_t);
|
||||||
uint64_t * offset
|
uint64_t * current = (uint64_t *)buff + (mid * item_size);
|
||||||
){
|
int rv = node_compare(current, item, &field_size);
|
||||||
int mid = count / 2;
|
|
||||||
int item_size = field_size + sizeof(uint64_t);
|
|
||||||
uint64_t * current = (uint64_t *)buff + (mid * item_size);
|
|
||||||
int rv = node_compare(current, item, &field_size);
|
|
||||||
|
|
||||||
if (rv == 0) {
|
if (rv == 0)
|
||||||
*offset = *(uint64_t *)(current + field_size);
|
{
|
||||||
return 0;
|
*offset = *(uint64_t *)(current + field_size);
|
||||||
} else if (count == 0)
|
return 0;
|
||||||
return -1;
|
}
|
||||||
else if (rv > 0)
|
else if (count == 0)
|
||||||
return binsearch(buff, item, mid, field_size, offset);
|
return -1;
|
||||||
|
else if (rv > 0)
|
||||||
|
return binsearch(buff, item, mid, field_size, offset);
|
||||||
|
|
||||||
return binsearch(current + item_size, item, count - mid, field_size, offset);
|
return binsearch(current + item_size, item,
|
||||||
|
count - mid, field_size, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
int libretrodb_find_entry(
|
int libretrodb_find_entry(libretrodb_t *db, const char *index_name,
|
||||||
libretrodb_t *db,
|
const void *key, struct rmsgpack_dom_value *out)
|
||||||
const char *index_name,
|
{
|
||||||
const void *key,
|
libretrodb_index_t idx;
|
||||||
struct rmsgpack_dom_value * out
|
int rv;
|
||||||
) {
|
void * buff;
|
||||||
libretrodb_index_t idx;
|
uint64_t offset;
|
||||||
int rv;
|
ssize_t bufflen, nread = 0;
|
||||||
void * buff;
|
|
||||||
uint64_t offset;
|
|
||||||
ssize_t bufflen, nread = 0;
|
|
||||||
|
|
||||||
if (libretrodb_find_index(db, index_name, &idx) < 0)
|
if (libretrodb_find_index(db, index_name, &idx) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
bufflen = idx.next;
|
bufflen = idx.next;
|
||||||
buff = malloc(bufflen);
|
buff = malloc(bufflen);
|
||||||
|
|
||||||
if (!buff)
|
if (!buff)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
while (nread < bufflen) {
|
while (nread < bufflen)
|
||||||
void * buff_ = (uint64_t *)buff + nread;
|
{
|
||||||
rv = read(db->fd, buff_, bufflen - nread);
|
void * buff_ = (uint64_t *)buff + nread;
|
||||||
if (rv <= 0) {
|
rv = read(db->fd, buff_, bufflen - nread);
|
||||||
free(buff);
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
nread += rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = binsearch(buff, key, db->count, idx.key_size, &offset);
|
if (rv <= 0)
|
||||||
free(buff);
|
{
|
||||||
|
free(buff);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
nread += rv;
|
||||||
|
}
|
||||||
|
|
||||||
if (rv == 0)
|
rv = binsearch(buff, key, db->count, idx.key_size, &offset);
|
||||||
lseek(db->fd, offset, SEEK_SET);
|
free(buff);
|
||||||
|
|
||||||
rv = rmsgpack_dom_read(db->fd, out);
|
if (rv == 0)
|
||||||
if (rv < 0)
|
lseek(db->fd, offset, SEEK_SET);
|
||||||
return rv;
|
|
||||||
|
rv = rmsgpack_dom_read(db->fd, out);
|
||||||
|
if (rv < 0)
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -299,38 +287,37 @@ int libretrodb_find_entry(
|
|||||||
int libretrodb_cursor_reset(libretrodb_cursor_t *cursor)
|
int libretrodb_cursor_reset(libretrodb_cursor_t *cursor)
|
||||||
{
|
{
|
||||||
cursor->eof = 0;
|
cursor->eof = 0;
|
||||||
return lseek(
|
return lseek(cursor->fd,
|
||||||
cursor->fd,
|
cursor->db->root + sizeof(libretrodb_header_t),
|
||||||
cursor->db->root + sizeof(libretrodb_header_t),
|
SEEK_SET);
|
||||||
SEEK_SET
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int libretrodb_cursor_read_item(
|
int libretrodb_cursor_read_item(libretrodb_cursor_t *cursor,
|
||||||
libretrodb_cursor_t *cursor,
|
struct rmsgpack_dom_value * out)
|
||||||
struct rmsgpack_dom_value * out
|
{
|
||||||
) {
|
int rv;
|
||||||
int rv;
|
|
||||||
if (cursor->eof)
|
if (cursor->eof)
|
||||||
return EOF;
|
return EOF;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
rv = rmsgpack_dom_read(cursor->fd, out);
|
rv = rmsgpack_dom_read(cursor->fd, out);
|
||||||
if (rv < 0)
|
if (rv < 0)
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
if (out->type == RDT_NULL) {
|
if (out->type == RDT_NULL)
|
||||||
cursor->eof = 1;
|
{
|
||||||
return EOF;
|
cursor->eof = 1;
|
||||||
}
|
return EOF;
|
||||||
|
}
|
||||||
|
|
||||||
if (cursor->query) {
|
if (cursor->query)
|
||||||
if (!libretrodb_query_filter(cursor->query, out)) {
|
{
|
||||||
goto retry;
|
if (!libretrodb_query_filter(cursor->query, out))
|
||||||
}
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -398,11 +385,9 @@ static uint64_t libretrodb_tell(libretrodb_t *db)
|
|||||||
return lseek(db->fd, 0, SEEK_CUR);
|
return lseek(db->fd, 0, SEEK_CUR);
|
||||||
}
|
}
|
||||||
|
|
||||||
int libretrodb_create_index(
|
int libretrodb_create_index(libretrodb_t *db,
|
||||||
libretrodb_t *db,
|
const char *name, const char *field_name)
|
||||||
const char *name,
|
{
|
||||||
const char *field_name
|
|
||||||
){
|
|
||||||
int rv;
|
int rv;
|
||||||
struct node_iter_ctx nictx;
|
struct node_iter_ctx nictx;
|
||||||
struct rmsgpack_dom_value key;
|
struct rmsgpack_dom_value key;
|
||||||
@ -411,14 +396,16 @@ int libretrodb_create_index(
|
|||||||
struct rmsgpack_dom_value * field;
|
struct rmsgpack_dom_value * field;
|
||||||
struct bintree tree;
|
struct bintree tree;
|
||||||
libretrodb_cursor_t cur;
|
libretrodb_cursor_t cur;
|
||||||
|
uint64_t idx_header_offset;
|
||||||
void * buff = NULL;
|
void * buff = NULL;
|
||||||
uint64_t * buff_u64 = NULL;
|
uint64_t * buff_u64 = NULL;
|
||||||
uint8_t field_size = 0;
|
uint8_t field_size = 0;
|
||||||
uint64_t idx_header_offset;
|
|
||||||
uint64_t item_loc = libretrodb_tell(db);
|
uint64_t item_loc = libretrodb_tell(db);
|
||||||
|
|
||||||
bintree_new(&tree, node_compare, &field_size);
|
bintree_new(&tree, node_compare, &field_size);
|
||||||
if (libretrodb_cursor_open(db, &cur, NULL) != 0) {
|
|
||||||
|
if (libretrodb_cursor_open(db, &cur, NULL) != 0)
|
||||||
|
{
|
||||||
rv = -1;
|
rv = -1;
|
||||||
goto clean;
|
goto clean;
|
||||||
}
|
}
|
||||||
@ -427,25 +414,33 @@ int libretrodb_create_index(
|
|||||||
key.string.len = strlen(field_name);
|
key.string.len = strlen(field_name);
|
||||||
/* We know we aren't going to change it */
|
/* We know we aren't going to change it */
|
||||||
key.string.buff = (char *) field_name;
|
key.string.buff = (char *) field_name;
|
||||||
while (libretrodb_cursor_read_item(&cur, &item) == 0) {
|
while (libretrodb_cursor_read_item(&cur, &item) == 0)
|
||||||
if (item.type != RDT_MAP) {
|
{
|
||||||
|
if (item.type != RDT_MAP)
|
||||||
|
{
|
||||||
rv = -EINVAL;
|
rv = -EINVAL;
|
||||||
printf("Only map keys are supported\n");
|
printf("Only map keys are supported\n");
|
||||||
goto clean;
|
goto clean;
|
||||||
}
|
}
|
||||||
|
|
||||||
field = rmsgpack_dom_value_map_value(&item, &key);
|
field = rmsgpack_dom_value_map_value(&item, &key);
|
||||||
if (!field) {
|
|
||||||
|
if (!field)
|
||||||
|
{
|
||||||
rv = -EINVAL;
|
rv = -EINVAL;
|
||||||
printf("field not found in item\n");
|
printf("field not found in item\n");
|
||||||
goto clean;
|
goto clean;
|
||||||
}
|
}
|
||||||
if (field->type != RDT_BINARY) {
|
|
||||||
|
if (field->type != RDT_BINARY)
|
||||||
|
{
|
||||||
rv = -EINVAL;
|
rv = -EINVAL;
|
||||||
printf("field is not binary\n");
|
printf("field is not binary\n");
|
||||||
goto clean;
|
goto clean;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field->binary.len == 0) {
|
if (field->binary.len == 0)
|
||||||
|
{
|
||||||
rv = -EINVAL;
|
rv = -EINVAL;
|
||||||
printf("field is empty\n");
|
printf("field is empty\n");
|
||||||
goto clean;
|
goto clean;
|
||||||
@ -453,14 +448,16 @@ int libretrodb_create_index(
|
|||||||
|
|
||||||
if (field_size == 0)
|
if (field_size == 0)
|
||||||
field_size = field->binary.len;
|
field_size = field->binary.len;
|
||||||
else if (field->binary.len != field_size) {
|
else if (field->binary.len != field_size)
|
||||||
|
{
|
||||||
rv = -EINVAL;
|
rv = -EINVAL;
|
||||||
printf("field is not of correct size\n");
|
printf("field is not of correct size\n");
|
||||||
goto clean;
|
goto clean;
|
||||||
}
|
}
|
||||||
|
|
||||||
buff = malloc(field_size + sizeof(uint64_t));
|
buff = malloc(field_size + sizeof(uint64_t));
|
||||||
if (!buff) {
|
if (!buff)
|
||||||
|
{
|
||||||
rv = -ENOMEM;
|
rv = -ENOMEM;
|
||||||
goto clean;
|
goto clean;
|
||||||
}
|
}
|
||||||
@ -469,7 +466,8 @@ int libretrodb_create_index(
|
|||||||
buff_u64 = (uint64_t *)buff + field_size;
|
buff_u64 = (uint64_t *)buff + field_size;
|
||||||
memcpy(buff_u64, &item_loc, sizeof(uint64_t));
|
memcpy(buff_u64, &item_loc, sizeof(uint64_t));
|
||||||
|
|
||||||
if (bintree_insert(&tree, buff) != 0) {
|
if (bintree_insert(&tree, buff) != 0)
|
||||||
|
{
|
||||||
printf("Value is not unique: ");
|
printf("Value is not unique: ");
|
||||||
rmsgpack_dom_value_print(field);
|
rmsgpack_dom_value_print(field);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@ -500,8 +498,7 @@ clean:
|
|||||||
rmsgpack_dom_value_free(&item);
|
rmsgpack_dom_value_free(&item);
|
||||||
if (buff)
|
if (buff)
|
||||||
free(buff);
|
free(buff);
|
||||||
if (cur.is_valid) {
|
if (cur.is_valid)
|
||||||
libretrodb_cursor_close(&cur);
|
libretrodb_cursor_close(&cur);
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -52,29 +52,19 @@ typedef struct libretrodb_cursor
|
|||||||
libretrodb_t * db;
|
libretrodb_t * db;
|
||||||
} libretrodb_cursor_t;
|
} libretrodb_cursor_t;
|
||||||
|
|
||||||
typedef int (* libretrodb_value_provider)(
|
typedef int (* libretrodb_value_provider)(void * ctx,
|
||||||
void * ctx,
|
struct rmsgpack_dom_value * out);
|
||||||
struct rmsgpack_dom_value * out
|
|
||||||
);
|
|
||||||
|
|
||||||
int libretrodb_create(
|
int libretrodb_create(int fd, libretrodb_value_provider value_provider,
|
||||||
int fd,
|
void * ctx);
|
||||||
libretrodb_value_provider value_provider,
|
|
||||||
void * ctx
|
|
||||||
);
|
|
||||||
|
|
||||||
void libretrodb_close(libretrodb_t * db);
|
void libretrodb_close(libretrodb_t * db);
|
||||||
|
|
||||||
int libretrodb_open(
|
int libretrodb_open(const char * path, libretrodb_t * db);
|
||||||
const char * path,
|
|
||||||
libretrodb_t * db
|
int libretrodb_create_index(libretrodb_t * db, const char *name,
|
||||||
);
|
const char *field_name);
|
||||||
|
|
||||||
int libretrodb_create_index(
|
|
||||||
libretrodb_t * db,
|
|
||||||
const char * name,
|
|
||||||
const char * field_name
|
|
||||||
);
|
|
||||||
int libretrodb_find_entry(
|
int libretrodb_find_entry(
|
||||||
libretrodb_t * db,
|
libretrodb_t * db,
|
||||||
const char * index_name,
|
const char * index_name,
|
||||||
@ -125,10 +115,8 @@ void *libretrodb_query_compile(
|
|||||||
|
|
||||||
void libretrodb_query_free(void *q);
|
void libretrodb_query_free(void *q);
|
||||||
|
|
||||||
int libretrodb_cursor_read_item(
|
int libretrodb_cursor_read_item(libretrodb_cursor_t * cursor,
|
||||||
libretrodb_cursor_t * cursor,
|
struct rmsgpack_dom_value * out);
|
||||||
struct rmsgpack_dom_value * out
|
|
||||||
);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -4,88 +4,104 @@
|
|||||||
#include "libretrodb.h"
|
#include "libretrodb.h"
|
||||||
#include "rmsgpack_dom.h"
|
#include "rmsgpack_dom.h"
|
||||||
|
|
||||||
int main(
|
int main(int argc, char ** argv)
|
||||||
int argc,
|
{
|
||||||
char ** argv
|
int rv;
|
||||||
){
|
libretrodb_t db;
|
||||||
int rv;
|
libretrodb_cursor_t cur;
|
||||||
libretrodb_t db;
|
|
||||||
libretrodb_cursor_t cur;
|
|
||||||
libretrodb_query_t *q;
|
libretrodb_query_t *q;
|
||||||
struct rmsgpack_dom_value item;
|
struct rmsgpack_dom_value item;
|
||||||
const char *command, *path, *query_exp, *error;
|
const char *command, *path, *query_exp, *error;
|
||||||
|
|
||||||
if (argc < 3) {
|
if (argc < 3)
|
||||||
printf("Usage: %s <db file> <command> [extra args...]\n", argv[0]);
|
{
|
||||||
printf("Available Commands:\n");
|
printf("Usage: %s <db file> <command> [extra args...]\n", argv[0]);
|
||||||
printf("\tlist\n");
|
printf("Available Commands:\n");
|
||||||
printf("\tcreate-index <index name> <field name>\n");
|
printf("\tlist\n");
|
||||||
printf("\tfind <query expression>\n");
|
printf("\tcreate-index <index name> <field name>\n");
|
||||||
return 1;
|
printf("\tfind <query expression>\n");
|
||||||
}
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
command = argv[2];
|
command = argv[2];
|
||||||
path = argv[1];
|
path = argv[1];
|
||||||
|
|
||||||
if ((rv = libretrodb_open(path, &db)) != 0) {
|
if ((rv = libretrodb_open(path, &db)) != 0)
|
||||||
printf("Could not open db file '%s': %s\n", path, strerror(-rv));
|
{
|
||||||
return 1;
|
printf("Could not open db file '%s': %s\n", path, strerror(-rv));
|
||||||
} else if (strcmp(command, "list") == 0) {
|
return 1;
|
||||||
if ((rv = libretrodb_cursor_open(&db, &cur, NULL)) != 0) {
|
}
|
||||||
printf("Could not open cursor: %s\n", strerror(-rv));
|
else if (strcmp(command, "list") == 0)
|
||||||
return 1;
|
{
|
||||||
}
|
if ((rv = libretrodb_cursor_open(&db, &cur, NULL)) != 0)
|
||||||
|
|
||||||
if (argc != 3) {
|
|
||||||
printf("Usage: %s <db file> list\n", argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
while (libretrodb_cursor_read_item(&cur, &item) == 0) {
|
|
||||||
rmsgpack_dom_value_print(&item);
|
|
||||||
printf("\n");
|
|
||||||
rmsgpack_dom_value_free(&item);
|
|
||||||
}
|
|
||||||
} else if (strcmp(command, "find") == 0) {
|
|
||||||
if (argc != 4) {
|
|
||||||
printf("Usage: %s <db file> find <query expression>\n", argv[0]);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
query_exp = argv[3];
|
|
||||||
error = NULL;
|
|
||||||
q = libretrodb_query_compile(&db, query_exp, strlen(query_exp), &error);
|
|
||||||
if (error) {
|
|
||||||
printf("%s\n", error);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((rv = libretrodb_cursor_open(&db, &cur, q)) != 0)
|
|
||||||
{
|
{
|
||||||
printf("Could not open cursor: %s\n", strerror(-rv));
|
printf("Could not open cursor: %s\n", strerror(-rv));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (libretrodb_cursor_read_item(&cur, &item) == 0)
|
if (argc != 3)
|
||||||
{
|
{
|
||||||
rmsgpack_dom_value_print(&item);
|
printf("Usage: %s <db file> list\n", argv[0]);
|
||||||
printf("\n");
|
return 1;
|
||||||
rmsgpack_dom_value_free(&item);
|
}
|
||||||
}
|
|
||||||
} else if (strcmp(command, "create-index") == 0) {
|
|
||||||
const char * index_name, * field_name;
|
|
||||||
|
|
||||||
if (argc != 5) {
|
while (libretrodb_cursor_read_item(&cur, &item) == 0)
|
||||||
printf("Usage: %s <db file> create-index <index name> <field name>\n", argv[0]);
|
{
|
||||||
return 1;
|
rmsgpack_dom_value_print(&item);
|
||||||
}
|
printf("\n");
|
||||||
|
rmsgpack_dom_value_free(&item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp(command, "find") == 0)
|
||||||
|
{
|
||||||
|
if (argc != 4)
|
||||||
|
{
|
||||||
|
printf("Usage: %s <db file> find <query expression>\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
index_name = argv[3];
|
query_exp = argv[3];
|
||||||
field_name = argv[4];
|
error = NULL;
|
||||||
|
q = libretrodb_query_compile(&db, query_exp, strlen(query_exp), &error);
|
||||||
|
|
||||||
libretrodb_create_index(&db, index_name, field_name);
|
if (error)
|
||||||
} else {
|
{
|
||||||
printf("Unkonwn command %s\n", argv[2]);
|
printf("%s\n", error);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
libretrodb_close(&db);
|
|
||||||
|
if ((rv = libretrodb_cursor_open(&db, &cur, q)) != 0)
|
||||||
|
{
|
||||||
|
printf("Could not open cursor: %s\n", strerror(-rv));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (libretrodb_cursor_read_item(&cur, &item) == 0)
|
||||||
|
{
|
||||||
|
rmsgpack_dom_value_print(&item);
|
||||||
|
printf("\n");
|
||||||
|
rmsgpack_dom_value_free(&item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp(command, "create-index") == 0)
|
||||||
|
{
|
||||||
|
const char * index_name, * field_name;
|
||||||
|
|
||||||
|
if (argc != 5)
|
||||||
|
{
|
||||||
|
printf("Usage: %s <db file> create-index <index name> <field name>\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
index_name = argv[3];
|
||||||
|
field_name = argv[4];
|
||||||
|
|
||||||
|
libretrodb_create_index(&db, index_name, field_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Unkonwn command %s\n", argv[2]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
libretrodb_close(&db);
|
||||||
}
|
}
|
||||||
|
1151
libretrodb/query.c
1151
libretrodb/query.c
File diff suppressed because it is too large
Load Diff
@ -7,9 +7,7 @@ void libretrodb_query_inc_ref(libretrodb_query_t *q);
|
|||||||
|
|
||||||
void libretrodb_query_dec_ref(libretrodb_query_t *q);
|
void libretrodb_query_dec_ref(libretrodb_query_t *q);
|
||||||
|
|
||||||
int libretrodb_query_filter(
|
int libretrodb_query_filter(libretrodb_query_t *q,
|
||||||
libretrodb_query_t *q,
|
struct rmsgpack_dom_value * v);
|
||||||
struct rmsgpack_dom_value * v
|
|
||||||
);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -55,32 +55,36 @@ static const uint8_t MPF_UINT64 = 0xcf;
|
|||||||
|
|
||||||
static const uint8_t MPF_NIL = 0xc0;
|
static const uint8_t MPF_NIL = 0xc0;
|
||||||
|
|
||||||
int rmsgpack_write_array_header(
|
int rmsgpack_write_array_header(int fd, uint32_t size)
|
||||||
int fd,
|
{
|
||||||
uint32_t size
|
uint16_t tmp_i16;
|
||||||
){
|
uint32_t tmp_i32;
|
||||||
uint16_t tmp_i16;
|
|
||||||
uint32_t tmp_i32;
|
if (size < 16)
|
||||||
if (size < 16) {
|
{
|
||||||
size = (size | MPF_FIXARRAY);
|
size = (size | MPF_FIXARRAY);
|
||||||
if (write(fd, &size, sizeof(int8_t)) == -1)
|
if (write(fd, &size, sizeof(int8_t)) == -1)
|
||||||
return -errno;
|
return -errno;
|
||||||
return sizeof(int8_t);
|
return sizeof(int8_t);
|
||||||
} else if (size == (uint16_t)size) {
|
}
|
||||||
if (write(fd, &MPF_ARRAY16, sizeof(MPF_ARRAY16)) == -1)
|
else if (size == (uint16_t)size)
|
||||||
return -errno;
|
{
|
||||||
tmp_i16 = httobe16(size);
|
if (write(fd, &MPF_ARRAY16, sizeof(MPF_ARRAY16)) == -1)
|
||||||
if (write(fd, (void *)(&tmp_i16), sizeof(uint16_t)) == -1)
|
return -errno;
|
||||||
return -errno;
|
tmp_i16 = httobe16(size);
|
||||||
return sizeof(int8_t) + sizeof(uint16_t);
|
if (write(fd, (void *)(&tmp_i16), sizeof(uint16_t)) == -1)
|
||||||
} else {
|
return -errno;
|
||||||
if (write(fd, &MPF_ARRAY32, sizeof(MPF_ARRAY32)) == -1)
|
return sizeof(int8_t) + sizeof(uint16_t);
|
||||||
return -errno;
|
}
|
||||||
tmp_i32 = httobe32(size);
|
else
|
||||||
if (write(fd, (void *)(&tmp_i32), sizeof(uint32_t)) == -1)
|
{
|
||||||
return -errno;
|
if (write(fd, &MPF_ARRAY32, sizeof(MPF_ARRAY32)) == -1)
|
||||||
return sizeof(int8_t) + sizeof(uint32_t);
|
return -errno;
|
||||||
}
|
tmp_i32 = httobe32(size);
|
||||||
|
if (write(fd, (void *)(&tmp_i32), sizeof(uint32_t)) == -1)
|
||||||
|
return -errno;
|
||||||
|
return sizeof(int8_t) + sizeof(uint32_t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int rmsgpack_write_map_header(
|
int rmsgpack_write_map_header(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user