diff options
author | Peng Wu <alexepico@gmail.com> | 2013-02-04 17:39:18 +0800 |
---|---|---|
committer | Peng Wu <alexepico@gmail.com> | 2013-02-04 17:39:18 +0800 |
commit | b0e127fb24247f038ec643803c93a09831667920 (patch) | |
tree | 66e5c488276136967226247d2e38c69f752588f8 /src | |
parent | dbd8fa467a1034c89d3c2ca9ab06228eae3b9cb9 (diff) | |
download | libpinyin-b0e127fb24247f038ec643803c93a09831667920.tar.gz libpinyin-b0e127fb24247f038ec643803c93a09831667920.tar.xz libpinyin-b0e127fb24247f038ec643803c93a09831667920.zip |
add mmap support
Diffstat (limited to 'src')
-rw-r--r-- | src/include/memory_chunk.h | 58 |
1 files changed, 44 insertions, 14 deletions
diff --git a/src/include/memory_chunk.h b/src/include/memory_chunk.h index 0d9eecb..29eb586 100644 --- a/src/include/memory_chunk.h +++ b/src/include/memory_chunk.h @@ -22,16 +22,21 @@ #ifndef MEMORY_CHUNK_H #define MEMORY_CHUNK_H +#include <config.h> #include <assert.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> +#ifdef HAVE_MMAP +#include <sys/mman.h> +#endif #include "stl_lite.h" namespace pinyin{ /* for unmanaged mode - * m_free_func == free , when memory is allocated by malloc + * m_free_func == free, when memory is allocated by malloc + * m_free_func == munmap, when memory is allocated by mmap * m_free_func == NULL, * when memory is in small protion of allocated area * m_free_func == other, @@ -46,7 +51,7 @@ namespace pinyin{ */ class MemoryChunk{ - typedef void (* free_func_t)(void *); + typedef void (* free_func_t)(...); private: char * m_data_begin; char * m_data_end; //one data pass the end. @@ -54,9 +59,22 @@ private: free_func_t m_free_func; private: + void freemem(){ + if ((free_func_t)free == m_free_func) + free(m_data_begin); +#ifdef HAVE_MMAP + else if ((free_func_t)munmap == m_free_func) + munmap(m_data_begin, capacity()); +#endif + else + assert(FALSE); + } + + void reset(){ - if ( m_free_func ) - (*m_free_func)(m_data_begin); + if (m_free_func) + freemem(); + m_data_begin = NULL; m_data_end = NULL; m_allocated = NULL; @@ -74,7 +92,7 @@ private: if ( 0 == extra_size ) return; size_t newsize; size_t cursize = size(); - if ( m_free_func != free ) { + if ( m_free_func != (free_func_t)free ) { /* copy on resize */ newsize = cursize + extra_size; /* do the copy */ @@ -83,15 +101,13 @@ private: memset(tmp, 0, newsize); memmove(tmp, m_data_begin, cursize); /* free the origin memory */ - if ( m_free_func){ - (*m_free_func)(m_data_begin); - } - + if (m_free_func) + freemem(); /* change varibles */ m_data_begin = tmp; m_data_end = m_data_begin + cursize; m_allocated = m_data_begin + newsize; - m_free_func = free; + m_free_func = (free_func_t)free; return; } /* the memory area is managed by this memory chunk */ @@ -192,8 +208,8 @@ public: * */ void set_chunk(void* begin, size_t length, free_func_t free_func){ - if ( m_free_func ) - m_free_func( m_data_begin ); + if (m_free_func) + freemem(); m_data_begin = (char *) begin; m_data_end = (char *) m_data_begin + length; @@ -312,7 +328,7 @@ public: * */ void compact_memory(){ - if ( m_free_func != free ) + if ( m_free_func != (free_func_t)free ) return; size_t newsize = size(); m_data_begin = (char *) realloc(m_data_begin, newsize); @@ -342,6 +358,19 @@ public: fseek(file, 0, SEEK_SET); int data_len = file_size; + +#ifdef HAVE_MMAP + int fd = fileno(file); + void* data = mmap(NULL, data_len, PROT_READ|PROT_WRITE, MAP_PRIVATE, + fd, 0); + + if (MAP_FAILED == data) { + fclose(file); + return false; + } + + set_chunk(data, data_len, (free_func_t)munmap); +#else void* data = malloc(data_len); if ( !data ){ fclose(file); @@ -349,7 +378,8 @@ public: } data_len = fread(data, 1, data_len, file); - set_chunk(data, data_len, free); + set_chunk(data, data_len, (free_func_t)free); +#endif fclose(file); return true; |