From 25593b5e6fea76ed7c08db586924032c0810c27e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Sun, 7 Nov 2010 00:47:39 +0200 Subject: squark: reorganize sources to src directory --- src/filterdb.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 src/filterdb.c (limited to 'src/filterdb.c') diff --git a/src/filterdb.c b/src/filterdb.c new file mode 100644 index 0000000..d3f4c6a --- /dev/null +++ b/src/filterdb.c @@ -0,0 +1,157 @@ +#include +#include +#include +#include +#include + +#include "filterdb.h" + +#define PAGE_SIZE 4096 +#define ALIGN(s,a) (((s) + a - 1) & ~(a - 1)) + +const char *sqdb_section_names[SQDB_SECTION_MAX] = { + [SQDB_SECTION_STRINGS] = "strings", + [SQDB_SECTION_CATEGORIES] = "categories", + [SQDB_SECTION_INDEX] = "index", + [SQDB_SECTION_INDEX_MPH] = "index_mph", + [SQDB_SECTION_KEYWORD] = "keyword", + [SQDB_SECTION_KEYWORD_MPH] = "keyword_mph", +}; + +static int sqdb_allocate(struct sqdb *db, size_t s, int wr) +{ + size_t old_size, new_size; + void *base; + int prot = PROT_READ; + + old_size = db->file_length; + new_size = ALIGN(db->file_length + s, PAGE_SIZE); + + if (new_size == ALIGN(db->file_length, PAGE_SIZE)) { + db->file_length += s; + return old_size; + } + + if (wr && ftruncate(db->fd, new_size) < 0) + return -1; + + if (db->mmap_base == NULL) { + if (wr) + prot |= PROT_WRITE; + base = mmap(NULL, new_size, prot, MAP_SHARED, db->fd, 0); + } else { + base = mremap(db->mmap_base, ALIGN(old_size, PAGE_SIZE), + new_size, MREMAP_MAYMOVE); + } + if (base == MAP_FAILED) + return -1; + + db->mmap_base = base; + db->file_length += ALIGN(s, 16); + + return old_size; +} + +int sqdb_open(struct sqdb *db, const char *fn) +{ + struct stat st; + + db->fd = open(fn, O_RDONLY); + if (db->fd < 0) + return -1; + + fstat(db->fd, &st); + + db->file_length = 0; + db->mmap_base = NULL; + sqdb_allocate(db, st.st_size, 0); + + return 0; +} + +int sqdb_create(struct sqdb *db, const char *fn) +{ + struct sqdb_header *hdr; + int rc; + + db->fd = open(fn, O_CREAT | O_TRUNC | O_RDWR, 0666); + if (db->fd < 0) + return -1; + + db->file_length = 0; + db->mmap_base = NULL; + + rc = sqdb_allocate(db, sizeof(struct sqdb_header), 1); + if (rc < 0) { + close(db->fd); + return rc; + } + + hdr = db->mmap_base; + strcpy(hdr->description, "Squark Filtering Database"); + hdr->version = 1; + hdr->magic = 0xdbdbdbdb; + hdr->num_sections = SQDB_SECTION_MAX; + + return 0; +} + +int sqdb_open(struct sqdb *db, const char *fn); + +void sqdb_close(struct sqdb *db) +{ + if (db->mmap_base) + munmap(db->mmap_base, ALIGN(db->file_length, PAGE_SIZE)); + close(db->fd); +} + +void *sqdb_section_create(struct sqdb *db, int id, uint32_t size) +{ + struct sqdb_header *hdr; + size_t pos; + + hdr = db->mmap_base; + if (hdr->section[id].offset || hdr->section[id].length) + return NULL; + + pos = sqdb_allocate(db, size, 1); + if (pos < 0) + return NULL; + + /* sqdb_allocate can remap mmap_base */ + hdr = db->mmap_base; + hdr->section[id].offset = pos; + hdr->section[id].length = size; + + return db->mmap_base + pos; +} + +void *sqdb_section_get(struct sqdb *db, int id, uint32_t *size) +{ + struct sqdb_header *hdr = db->mmap_base; + + if (hdr->section[id].offset == 0) + return NULL; + + if (size) + *size = hdr->section[id].length; + + return db->mmap_base + hdr->section[id].offset; +} + +blob_t sqdb_get_string_literal(struct sqdb *db, uint32_t encoded_ptr) +{ + unsigned char *ptr; + unsigned int len, off; + + ptr = sqdb_section_get(db, SQDB_SECTION_STRINGS, NULL); + if (ptr == NULL) + return BLOB_NULL; + + off = encoded_ptr >> SQDB_LENGTH_BITS; + len = encoded_ptr & ((1 << SQDB_LENGTH_BITS) - 1); + if (len == 0) + len = ptr[off++]; + + return BLOB_PTR_LEN(ptr + off, len); +} -- cgit v1.2.3