summaryrefslogtreecommitdiffstats
path: root/src/include/memory_chunk.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/memory_chunk.h')
-rw-r--r--src/include/memory_chunk.h58
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;