diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:35 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:35 -0800 |
commit | dfb3f050a7cebd2030ea23dc6fa8964530e4ddcc (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /libdb/db_manage.c | |
parent | b9958da7adae1c7d4482e958b371401eef387a39 (diff) | |
download | oprofile-dfb3f050a7cebd2030ea23dc6fa8964530e4ddcc.tar.gz |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'libdb/db_manage.c')
-rw-r--r-- | libdb/db_manage.c | 311 |
1 files changed, 0 insertions, 311 deletions
diff --git a/libdb/db_manage.c b/libdb/db_manage.c deleted file mode 100644 index d8a6fcb..0000000 --- a/libdb/db_manage.c +++ /dev/null @@ -1,311 +0,0 @@ -/** - * @file db_manage.c - * Management of a DB file - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author Philippe Elie - */ - -#define _GNU_SOURCE - -#include <stdlib.h> -#ifndef ANDROID -#include <sys/fcntl.h> -#else -#include <fcntl.h> -#endif -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <stdio.h> - -#include "odb.h" -#include "op_string.h" -#include "op_libiberty.h" - - -static __inline odb_descr_t * odb_to_descr(odb_data_t * data) -{ - return (odb_descr_t *)(((char*)data->base_memory) + data->sizeof_header); -} - - -static __inline odb_node_t * odb_to_node_base(odb_data_t * data) -{ - return (odb_node_t *)(((char *)data->base_memory) + data->offset_node); -} - - -static __inline odb_index_t * odb_to_hash_base(odb_data_t * data) -{ - return (odb_index_t *)(((char *)data->base_memory) + - data->offset_node + - (data->descr->size * sizeof(odb_node_t))); -} - - -/** - * return the number of bytes used by hash table, node table and header. - */ -static unsigned int tables_size(odb_data_t const * data, odb_node_nr_t node_nr) -{ - size_t size; - - size = node_nr * (sizeof(odb_index_t) * BUCKET_FACTOR); - size += node_nr * sizeof(odb_node_t); - size += data->offset_node; - - return size; -} - - -int odb_grow_hashtable(odb_data_t * data) -{ - unsigned int old_file_size; - unsigned int new_file_size; - unsigned int pos; - void * new_map; - - old_file_size = tables_size(data, data->descr->size); - new_file_size = tables_size(data, data->descr->size * 2); - - if (ftruncate(data->fd, new_file_size)) - return 1; - - new_map = mremap(data->base_memory, - old_file_size, new_file_size, MREMAP_MAYMOVE); - - if (new_map == MAP_FAILED) - return 1; - - data->base_memory = new_map; - data->descr = odb_to_descr(data); - data->descr->size *= 2; - data->node_base = odb_to_node_base(data); - data->hash_base = odb_to_hash_base(data); - data->hash_mask = (data->descr->size * BUCKET_FACTOR) - 1; - - /* rebuild the hash table, node zero is never used. This works - * because layout of file is node table then hash table, - * sizeof(node) > sizeof(bucket) and when we grow table we - * double size ==> old hash table and new hash table can't - * overlap so on the new hash table is entirely in the new - * memory area (the grown part) and we know the new hash - * hash table is zeroed. That's why we don't need to zero init - * the new table */ - /* OK: the above is not exact - * if BUCKET_FACTOR < sizeof(bd_node_t) / sizeof(bd_node_nr_t) - * all things are fine and we don't need to init the hash - * table because in this case the new hash table is completely - * inside the new growed part. Avoiding to touch this memory is - * useful. - */ -#if 0 - for (pos = 0 ; pos < data->descr->size*BUCKET_FACTOR ; ++pos) - data->hash_base[pos] = 0; -#endif - - for (pos = 1; pos < data->descr->current_size; ++pos) { - odb_node_t * node = &data->node_base[pos]; - size_t index = odb_do_hash(data, node->key); - node->next = data->hash_base[index]; - data->hash_base[index] = pos; - } - - return 0; -} - - -void odb_init(odb_t * odb) -{ - odb->data = NULL; -} - - -/* the default number of page, calculated to fit in 4096 bytes */ -#define DEFAULT_NODE_NR(offset_node) 128 -#define FILES_HASH_SIZE 512 - -static struct list_head files_hash[FILES_HASH_SIZE]; - - -static void init_hash() -{ - size_t i; - for (i = 0; i < FILES_HASH_SIZE; ++i) - list_init(&files_hash[i]); -} - - -static odb_data_t * -find_samples_data(size_t hash, char const * filename) -{ - struct list_head * pos; - - /* FIXME: maybe an initial init routine ? */ - if (files_hash[0].next == NULL) { - init_hash(); - return NULL; - } - - list_for_each(pos, &files_hash[hash]) { - odb_data_t * entry = list_entry(pos, odb_data_t, list); - if (strcmp(entry->filename, filename) == 0) - return entry; - } - - return NULL; -} - - -int odb_open(odb_t * odb, char const * filename, enum odb_rw rw, - size_t sizeof_header) -{ - struct stat stat_buf; - odb_node_nr_t nr_node; - odb_data_t * data; - size_t hash; - int err = 0; - - int flags = (rw == ODB_RDWR) ? (O_CREAT | O_RDWR) : O_RDONLY; - int mmflags = (rw == ODB_RDWR) ? (PROT_READ | PROT_WRITE) : PROT_READ; - - hash = op_hash_string(filename) % FILES_HASH_SIZE; - data = find_samples_data(hash, filename); - if (data) { - odb->data = data; - data->ref_count++; - return 0; - } - - data = xmalloc(sizeof(odb_data_t)); - memset(data, '\0', sizeof(odb_data_t)); - list_init(&data->list); - data->offset_node = sizeof_header + sizeof(odb_descr_t); - data->sizeof_header = sizeof_header; - data->ref_count = 1; - data->filename = xstrdup(filename); - - data->fd = open(filename, flags, 0644); - if (data->fd < 0) { - err = errno; - goto out; - } - - if (fstat(data->fd, &stat_buf)) { - err = errno; - goto fail; - } - - if (stat_buf.st_size == 0) { - size_t file_size; - - if (rw == ODB_RDONLY) { - err = EIO; - goto fail; - } - - nr_node = DEFAULT_NODE_NR(data->offset_node); - - file_size = tables_size(data, nr_node); - if (ftruncate(data->fd, file_size)) { - err = errno; - goto fail; - } - } else { - /* Calculate nr node allowing a sanity check later */ - nr_node = (stat_buf.st_size - data->offset_node) / - ((sizeof(odb_index_t) * BUCKET_FACTOR) + sizeof(odb_node_t)); - } - - data->base_memory = mmap(0, tables_size(data, nr_node), mmflags, - MAP_SHARED, data->fd, 0); - - if (data->base_memory == MAP_FAILED) { - err = errno; - goto fail; - } - - data->descr = odb_to_descr(data); - - if (stat_buf.st_size == 0) { - data->descr->size = nr_node; - /* page zero is not used */ - data->descr->current_size = 1; - } else { - /* file already exist, sanity check nr node */ - if (nr_node != data->descr->size) { - err = EINVAL; - goto fail_unmap; - } - } - - data->hash_base = odb_to_hash_base(data); - data->node_base = odb_to_node_base(data); - data->hash_mask = (data->descr->size * BUCKET_FACTOR) - 1; - - list_add(&data->list, &files_hash[hash]); - odb->data = data; -out: - return err; -fail_unmap: - munmap(data->base_memory, tables_size(data, nr_node)); -fail: - close(data->fd); - free(data->filename); - free(data); - odb->data = NULL; - goto out; -} - - -void odb_close(odb_t * odb) -{ - odb_data_t * data = odb->data; - - if (data) { - data->ref_count--; - if (data->ref_count == 0) { - size_t size = tables_size(data, data->descr->size); - list_del(&data->list); - munmap(data->base_memory, size); - if (data->fd >= 0) - close(data->fd); - free(data->filename); - free(data); - odb->data = NULL; - } - } -} - - -int odb_open_count(odb_t const * odb) -{ - if (!odb->data) - return 0; - return odb->data->ref_count; -} - - -void * odb_get_data(odb_t * odb) -{ - return odb->data->base_memory; -} - - -void odb_sync(odb_t const * odb) -{ - odb_data_t * data = odb->data; - size_t size; - - if (!data) - return; - - size = tables_size(data, data->descr->size); - msync(data->base_memory, size, MS_ASYNC); -} |