[evolution-data-server] Add CamelMemChunk (copy of EMemChunk).
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Add CamelMemChunk (copy of EMemChunk).
- Date: Sun, 25 Sep 2011 15:59:06 +0000 (UTC)
commit 5ce39d3904b8234a8aebe497fd82bc5b84d73cba
Author: Matthew Barnes <mbarnes redhat com>
Date: Sat Sep 3 15:19:47 2011 -0400
Add CamelMemChunk (copy of EMemChunk).
To further erode Camel's dependence on libedataserver.
camel/Makefile.am | 2 +
camel/camel-certdb.c | 8 +-
camel/camel-certdb.h | 3 +-
camel/camel-folder-summary.h | 7 +-
camel/camel-folder-thread.c | 34 +-
camel/camel-folder-thread.h | 3 +-
camel/camel-memchunk.c | 459 +++++++++++++++++++++++++
camel/camel-memchunk.h | 49 +++
camel/camel-store-summary.c | 4 +-
camel/camel-store-summary.h | 3 +-
camel/camel-trie.c | 19 +-
camel/camel.h | 1 +
docs/reference/camel/camel-docs.sgml | 5 +
docs/reference/camel/camel-sections.txt | 12 +
docs/reference/camel/tmpl/camel-memchunk.sgml | 89 +++++
15 files changed, 656 insertions(+), 42 deletions(-)
---
diff --git a/camel/Makefile.am b/camel/Makefile.am
index d58ac77..d74ab7f 100644
--- a/camel/Makefile.am
+++ b/camel/Makefile.am
@@ -196,6 +196,7 @@ libcamel_1_2_la_SOURCES = \
camel-list-utils.c \
camel-lock.c \
camel-medium.c \
+ camel-memchunk.c \
camel-mempool.c \
camel-mime-filter-basic.c \
camel-mime-filter-bestenc.c \
@@ -267,6 +268,7 @@ libcamelinclude_HEADERS = \
camel-lock-client.h \
camel-lock.h \
camel-medium.h \
+ camel-memchunk.h \
camel-mempool.h \
camel-mime-filter-basic.h \
camel-mime-filter-bestenc.h \
diff --git a/camel/camel-certdb.c b/camel/camel-certdb.c
index 68089d4..9241a1c 100644
--- a/camel/camel-certdb.c
+++ b/camel/camel-certdb.c
@@ -34,8 +34,6 @@
#include <glib/gstdio.h>
-#include <libedataserver/e-memory.h>
-
#include "camel-certdb.h"
#include "camel-file-utils.h"
#include "camel-win32.h"
@@ -79,7 +77,7 @@ certdb_finalize (GObject *object)
g_free (certdb->filename);
if (certdb->cert_chunks)
- e_memchunk_destroy (certdb->cert_chunks);
+ camel_memchunk_destroy (certdb->cert_chunks);
g_mutex_free (priv->db_lock);
g_mutex_free (priv->io_lock);
@@ -478,7 +476,7 @@ certdb_cert_new (CamelCertDB *certdb)
CamelCert *cert;
if (certdb->cert_chunks)
- cert = e_memchunk_alloc0 (certdb->cert_chunks);
+ cert = camel_memchunk_alloc0 (certdb->cert_chunks);
else
cert = g_malloc0 (certdb->cert_size);
@@ -548,7 +546,7 @@ camel_certdb_cert_unref (CamelCertDB *certdb,
if (cert->refcount <= 1) {
class->cert_free (certdb, cert);
if (certdb->cert_chunks)
- e_memchunk_free (certdb->cert_chunks, cert);
+ camel_memchunk_free (certdb->cert_chunks, cert);
else
g_free (cert);
} else {
diff --git a/camel/camel-certdb.h b/camel/camel-certdb.h
index 521a22f..c289e72 100644
--- a/camel/camel-certdb.h
+++ b/camel/camel-certdb.h
@@ -28,6 +28,7 @@
#define CAMEL_CERTDB_H
#include <stdio.h>
+#include <camel/camel-memchunk.h>
#include <camel/camel-object.h>
/* Standard GObject macros */
@@ -109,7 +110,7 @@ struct _CamelCertDB {
guint32 cert_size;
- struct _EMemChunk *cert_chunks;
+ CamelMemChunk *cert_chunks;
GPtrArray *certs;
GHashTable *cert_hash;
diff --git a/camel/camel-folder-summary.h b/camel/camel-folder-summary.h
index 9423643..aaba7ae 100644
--- a/camel/camel-folder-summary.h
+++ b/camel/camel-folder-summary.h
@@ -29,9 +29,10 @@
#include <stdio.h>
#include <time.h>
+#include <camel/camel-index.h>
+#include <camel/camel-memchunk.h>
#include <camel/camel-mime-message.h>
#include <camel/camel-mime-parser.h>
-#include <camel/camel-index.h>
/* Standard GObject macros */
#define CAMEL_TYPE_FOLDER_SUMMARY \
@@ -249,8 +250,8 @@ struct _CamelFolderSummary {
guint32 visible_count;
/* memory allocators (setup automatically) */
- struct _EMemChunk *message_info_chunks;
- struct _EMemChunk *content_info_chunks;
+ CamelMemChunk *message_info_chunks;
+ CamelMemChunk *content_info_chunks;
gchar *summary_path;
gboolean build_content; /* do we try and parse/index the content, or not? */
diff --git a/camel/camel-folder-thread.c b/camel/camel-folder-thread.c
index e00c623..0c3f9b9 100644
--- a/camel/camel-folder-thread.c
+++ b/camel/camel-folder-thread.c
@@ -33,8 +33,6 @@
#include <sys/stat.h>
#include <sys/types.h>
-#include <libedataserver/e-memory.h>
-
#include "camel-folder-thread.h"
#define d(x)
@@ -119,7 +117,7 @@ prune_empty (CamelFolderThread *thread,
d(printf("removing empty node\n"));
lastc->next = c->next;
m (memset (c, 0xfe, sizeof (*c)));
- e_memchunk_free (thread->node_chunks, c);
+ camel_memchunk_free (thread->node_chunks, c);
continue;
}
if (c->parent || c->child->next == NULL) {
@@ -274,7 +272,7 @@ group_root_set (CamelFolderThread *thread,
scan->next = c->child;
clast->next = c->next;
m (memset (c, 0xee, sizeof (*c)));
- e_memchunk_free (thread->node_chunks, c);
+ camel_memchunk_free (thread->node_chunks, c);
continue;
} if (c->message == NULL && container->message != NULL) {
d(printf("container is non-empty parent\n"));
@@ -301,7 +299,7 @@ group_root_set (CamelFolderThread *thread,
remove_node (cp, container, &clast);
remove_node (cp, c, &clast);
- scan = e_memchunk_alloc0 (thread->node_chunks);
+ scan = camel_memchunk_alloc0 (thread->node_chunks);
scan->root_subject = c->root_subject;
scan->re = c->re && container->re;
@@ -471,16 +469,16 @@ thread_summary (CamelFolderThread *thread,
/* if duplicate, just make out it is a no-id message, but try and insert it
* into the right spot in the tree */
d(printf("doing: (duplicate message id)\n"));
- c = e_memchunk_alloc0 (thread->node_chunks);
+ c = camel_memchunk_alloc0 (thread->node_chunks);
g_hash_table_insert (no_id_table, (gpointer) mi, c);
} else if (!c) {
d(printf("doing : %08x%08x (%s)\n", mid->id.part.hi, mid->id.part.lo, camel_message_info_subject(mi)));
- c = e_memchunk_alloc0 (thread->node_chunks);
+ c = camel_memchunk_alloc0 (thread->node_chunks);
g_hash_table_insert (id_table, (gpointer) mid, c);
}
} else {
d(printf("doing : (no message id)\n"));
- c = e_memchunk_alloc0 (thread->node_chunks);
+ c = camel_memchunk_alloc0 (thread->node_chunks);
g_hash_table_insert (no_id_table, (gpointer) mi, c);
}
@@ -501,7 +499,7 @@ thread_summary (CamelFolderThread *thread,
c = g_hash_table_lookup (id_table, &references->references[j]);
if (c == NULL) {
d(printf("%s (%s) not found\n", G_STRLOC, G_STRFUNC));
- c = e_memchunk_alloc0 (thread->node_chunks);
+ c = camel_memchunk_alloc0 (thread->node_chunks);
g_hash_table_insert (id_table, (gpointer) &references->references[j], c);
} else
found = TRUE;
@@ -569,7 +567,7 @@ thread_summary (CamelFolderThread *thread,
newtop->next = child->next;
c = newtop;
m (memset (child, 0xde, sizeof (*child)));
- e_memchunk_free (thread->node_chunks, child);
+ camel_memchunk_free (thread->node_chunks, child);
} else {
c = child;
}
@@ -629,7 +627,7 @@ camel_folder_thread_messages_new (CamelFolder *folder,
thread->refcount = 1;
thread->subject = thread_subject;
thread->tree = NULL;
- thread->node_chunks = e_memchunk_new (32, sizeof (CamelFolderThreadNode));
+ thread->node_chunks = camel_memchunk_new (32, sizeof (CamelFolderThreadNode));
thread->folder = g_object_ref (folder);
camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
@@ -704,8 +702,8 @@ camel_folder_thread_messages_apply (CamelFolderThread *thread,
g_hash_table_destroy (table);
thread->tree = NULL;
- e_memchunk_destroy (thread->node_chunks);
- thread->node_chunks = e_memchunk_new (32, sizeof (CamelFolderThreadNode));
+ camel_memchunk_destroy (thread->node_chunks);
+ thread->node_chunks = camel_memchunk_new (32, sizeof (CamelFolderThreadNode));
thread_summary (thread, all);
g_ptr_array_free (thread->summary, TRUE);
@@ -740,7 +738,7 @@ camel_folder_thread_messages_unref (CamelFolderThread *thread)
g_ptr_array_free (thread->summary, TRUE);
g_object_unref (thread->folder);
}
- e_memchunk_destroy (thread->node_chunks);
+ camel_memchunk_destroy (thread->node_chunks);
g_free (thread);
}
@@ -771,7 +769,7 @@ camel_folder_thread_messages_new_summary (GPtrArray *summary)
thread = g_malloc (sizeof (*thread));
thread->refcount = 1;
thread->tree = NULL;
- thread->node_chunks = e_memchunk_new (32, sizeof (CamelFolderThreadNode));
+ thread->node_chunks = camel_memchunk_new (32, sizeof (CamelFolderThreadNode));
thread->folder = NULL;
thread->summary = NULL;
@@ -823,7 +821,7 @@ camel_folder_thread_messages_add (CamelFolderThread *thread,
/* reset the tree, and rebuild fully */
thread->tree = NULL;
- e_memchunk_empty (thread->node_chunks);
+ camel_memchunk_empty (thread->node_chunks);
thread_summary (thread, all);
}
@@ -863,7 +861,7 @@ remove_uid_node_rec (CamelFolderThread *thread,
rest = next->next;
node->next = child;
- e_memchunk_free (thread->node_chunks, next);
+ camel_memchunk_free (thread->node_chunks, next);
next = child;
do {
lchild = child;
@@ -880,7 +878,7 @@ remove_uid_node_rec (CamelFolderThread *thread,
* node
* rest */
node->next = next->next;
- e_memchunk_free (thread->node_chunks, next);
+ camel_memchunk_free (thread->node_chunks, next);
next = node->next;
}
} else {
diff --git a/camel/camel-folder-thread.h b/camel/camel-folder-thread.h
index 850c918..bd08039 100644
--- a/camel/camel-folder-thread.h
+++ b/camel/camel-folder-thread.h
@@ -28,6 +28,7 @@
#include <camel/camel-folder-summary.h>
#include <camel/camel-folder.h>
+#include <camel/camel-memchunk.h>
G_BEGIN_DECLS
@@ -44,7 +45,7 @@ typedef struct _CamelFolderThread {
guint32 subject : 1;
struct _CamelFolderThreadNode *tree;
- struct _EMemChunk *node_chunks;
+ CamelMemChunk *node_chunks;
CamelFolder *folder;
GPtrArray *summary;
} CamelFolderThread;
diff --git a/camel/camel-memchunk.c b/camel/camel-memchunk.c
new file mode 100644
index 0000000..ffa562a
--- /dev/null
+++ b/camel/camel-memchunk.c
@@ -0,0 +1,459 @@
+/*
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * Authors: Michael Zucchi <notzed ximian com>
+ * Jacob Berkman <jacob ximian com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ *
+*/
+
+#include "camel-memchunk.h"
+
+#include <string.h> /* memset() */
+
+/*#define TIMEIT*/
+
+#ifdef TIMEIT
+#include <sys/time.h>
+#include <unistd.h>
+
+struct timeval timeit_start;
+
+static void
+time_start (const gchar *desc)
+{
+ gettimeofday (&timeit_start, NULL);
+ printf("starting: %s\n", desc);
+}
+
+static void
+time_end (const gchar *desc)
+{
+ gulong diff;
+ struct timeval end;
+
+ gettimeofday (&end, NULL);
+ diff = end.tv_sec * 1000 + end.tv_usec / 1000;
+ diff -= timeit_start.tv_sec * 1000 + timeit_start.tv_usec / 1000;
+ printf("%s took %ld.%03ld seconds\n",
+ desc, diff / 1000, diff % 1000);
+}
+#else
+#define time_start(x)
+#define time_end(x)
+#endif
+
+typedef struct _MemChunkFreeNode {
+ struct _MemChunkFreeNode *next;
+ guint atoms;
+} MemChunkFreeNode;
+
+/**
+ * CamelMemChunk:
+ *
+ * Since: 3.4
+ **/
+struct _CamelMemChunk {
+ guint blocksize; /* number of atoms in a block */
+ guint atomsize; /* size of each atom */
+ GPtrArray *blocks; /* blocks of raw memory */
+ struct _MemChunkFreeNode *free;
+};
+
+/**
+ * camel_memchunk_new:
+ * @atomcount: the number of atoms stored in a single malloc'd block of memory
+ * @atomsize: the size of each allocation
+ *
+ * Create a new #CamelMemChunk header. Memchunks are an efficient way to
+ * allocate and deallocate identical sized blocks of memory quickly, and
+ * space efficiently.
+ *
+ * camel_memchunks are effectively the same as gmemchunks, only faster (much),
+ * and they use less memory overhead for housekeeping.
+ *
+ * Returns: a new #CamelMemChunk
+ *
+ * Since: 3.4
+ **/
+CamelMemChunk *
+camel_memchunk_new (gint atomcount,
+ gint atomsize)
+{
+ CamelMemChunk *memchunk = g_malloc (sizeof (*memchunk));
+
+ memchunk->blocksize = atomcount;
+ memchunk->atomsize = MAX (atomsize, sizeof (MemChunkFreeNode));
+ memchunk->blocks = g_ptr_array_new ();
+ memchunk->free = NULL;
+
+ return memchunk;
+}
+
+/**
+ * camel_memchunk_alloc:
+ * @memchunk: an #CamelMemChunk
+ *
+ * Allocate a new atom size block of memory from an #CamelMemChunk.
+ * Free the returned atom with camel_memchunk_free().
+ *
+ * Returns: an allocated block of memory
+ *
+ * Since: 3.4
+ **/
+gpointer
+camel_memchunk_alloc (CamelMemChunk *memchunk)
+{
+ gchar *b;
+ MemChunkFreeNode *f;
+ gpointer mem;
+
+ f = memchunk->free;
+ if (f) {
+ f->atoms--;
+ if (f->atoms > 0) {
+ mem = ((gchar *) f) + (f->atoms * memchunk->atomsize);
+ } else {
+ mem = f;
+ memchunk->free = memchunk->free->next;
+ }
+ return mem;
+ } else {
+ b = g_malloc (memchunk->blocksize * memchunk->atomsize);
+ g_ptr_array_add (memchunk->blocks, b);
+ f = (MemChunkFreeNode *) &b[memchunk->atomsize];
+ f->atoms = memchunk->blocksize - 1;
+ f->next = NULL;
+ memchunk->free = f;
+ return b;
+ }
+}
+
+/**
+ * camel_memchunk_alloc0:
+ * @memchunk: an #CamelMemChunk
+ *
+ * Allocate a new atom size block of memory from an #CamelMemChunk,
+ * and fill the memory with zeros. Free the returned atom with
+ * camel_memchunk_free().
+ *
+ * Returns: an allocated block of memory
+ *
+ * Since: 3.4
+ **/
+gpointer
+camel_memchunk_alloc0 (CamelMemChunk *memchunk)
+{
+ gpointer mem;
+
+ mem = camel_memchunk_alloc (memchunk);
+ memset (mem, 0, memchunk->atomsize);
+
+ return mem;
+}
+
+/**
+ * camel_memchunk_free:
+ * @memchunk: an #CamelMemChunk
+ * @mem: address of atom to free
+ *
+ * Free a single atom back to the free pool of atoms in the given
+ * memchunk.
+ *
+ * Since: 3.4
+ **/
+void
+camel_memchunk_free (CamelMemChunk *memchunk,
+ gpointer mem)
+{
+ MemChunkFreeNode *f;
+
+ /* Put the location back in the free list. If we knew if the
+ * preceeding or following cells were free, we could merge the
+ * free nodes, but it doesn't really add much. */
+ f = mem;
+ f->next = memchunk->free;
+ memchunk->free = f;
+ f->atoms = 1;
+
+ /* We could store the free list sorted - we could then do the above,
+ * and also probably improve the locality of reference properties for
+ * the allocator. (And it would simplify some other algorithms at
+ * that, but slow this one down significantly.) */
+}
+
+/**
+ * camel_memchunk_empty:
+ * @memchunk: an #CamelMemChunk
+ *
+ * Clean out the memchunk buffers. Marks all allocated memory as free blocks,
+ * but does not give it back to the system. Can be used if the memchunk
+ * is to be used repeatedly.
+ *
+ * Since: 3.4
+ **/
+void
+camel_memchunk_empty (CamelMemChunk *memchunk)
+{
+ MemChunkFreeNode *f, *h = NULL;
+ gint i;
+
+ for (i = 0; i < memchunk->blocks->len; i++) {
+ f = (MemChunkFreeNode *) memchunk->blocks->pdata[i];
+ f->atoms = memchunk->blocksize;
+ f->next = h;
+ h = f;
+ }
+
+ memchunk->free = h;
+}
+
+struct _cleaninfo {
+ struct _cleaninfo *next;
+ gchar *base;
+ gint count;
+ gint size; /* just so tree_search has it, sigh */
+};
+
+static gint
+tree_compare (struct _cleaninfo *a,
+ struct _cleaninfo *b)
+{
+ if (a->base < b->base)
+ return -1;
+ else if (a->base > b->base)
+ return 1;
+ return 0;
+}
+
+static gint
+tree_search (struct _cleaninfo *a,
+ gchar *mem)
+{
+ if (a->base <= mem) {
+ if (mem < &a->base[a->size])
+ return 0;
+ return 1;
+ }
+ return -1;
+}
+
+/**
+ * camel_memchunk_clean:
+ * @memchunk: an #CamelMemChunk
+ *
+ * Scan all empty blocks and check for blocks which can be free'd
+ * back to the system.
+ *
+ * This routine may take a while to run if there are many allocated
+ * memory blocks (if the total number of allocations is many times
+ * greater than atomcount).
+ *
+ * Since: 3.4
+ **/
+void
+camel_memchunk_clean (CamelMemChunk *memchunk)
+{
+ GTree *tree;
+ gint i;
+ MemChunkFreeNode *f;
+ struct _cleaninfo *ci, *hi = NULL;
+
+ f = memchunk->free;
+ if (memchunk->blocks->len == 0 || f == NULL)
+ return;
+
+ /* first, setup the tree/list so we can map free block addresses to block addresses */
+ tree = g_tree_new ((GCompareFunc) tree_compare);
+ for (i = 0; i < memchunk->blocks->len; i++) {
+ ci = alloca (sizeof (*ci));
+ ci->count = 0;
+ ci->base = memchunk->blocks->pdata[i];
+ ci->size = memchunk->blocksize * memchunk->atomsize;
+ g_tree_insert (tree, ci, ci);
+ ci->next = hi;
+ hi = ci;
+ }
+
+ /* now, scan all free nodes, and count them in their tree node */
+ while (f) {
+ ci = g_tree_search (tree, (GCompareFunc) tree_search, f);
+ if (ci) {
+ ci->count += f->atoms;
+ } else {
+ g_warning("error, can't find free node in memory block\n");
+ }
+ f = f->next;
+ }
+
+ /* if any nodes are all free, free & unlink them */
+ ci = hi;
+ while (ci) {
+ if (ci->count == memchunk->blocksize) {
+ MemChunkFreeNode *prev = NULL;
+
+ f = memchunk->free;
+ while (f) {
+ if (tree_search (ci, (gpointer) f) == 0) {
+ /* prune this node from our free-node list */
+ if (prev)
+ prev->next = f->next;
+ else
+ memchunk->free = f->next;
+ } else {
+ prev = f;
+ }
+
+ f = f->next;
+ }
+
+ g_ptr_array_remove_fast (memchunk->blocks, ci->base);
+ g_free (ci->base);
+ }
+ ci = ci->next;
+ }
+
+ g_tree_destroy (tree);
+}
+
+/**
+ * camel_memchunk_destroy:
+ * @memchunk: an #CamelMemChunk
+ *
+ * Free the memchunk header, and all associated memory.
+ *
+ * Since: 3.4
+ **/
+void
+camel_memchunk_destroy (CamelMemChunk *memchunk)
+{
+ gint i;
+
+ if (memchunk == NULL)
+ return;
+
+ for (i = 0; i < memchunk->blocks->len; i++)
+ g_free (memchunk->blocks->pdata[i]);
+
+ g_ptr_array_free (memchunk->blocks, TRUE);
+
+ g_free (memchunk);
+}
+
+#if 0
+
+#define CHUNK_SIZE (20)
+#define CHUNK_COUNT (32)
+
+#define s(x)
+
+main ()
+{
+ gint i;
+ MemChunk *mc;
+ gpointer mem, *last;
+ GMemChunk *gmc;
+ struct _EStrv *s;
+
+ s = strv_new (8);
+ s = strv_set(s, 1, "Testing 1");
+ s = strv_set(s, 2, "Testing 2");
+ s = strv_set(s, 3, "Testing 3");
+ s = strv_set(s, 4, "Testing 4");
+ s = strv_set(s, 5, "Testing 5");
+ s = strv_set(s, 6, "Testing 7");
+
+ for (i = 0; i < 8; i++) {
+ printf("s[%d] = %s\n", i, strv_get(s, i));
+ }
+
+ s (sleep (5));
+
+ printf("packing ...\n");
+ s = strv_pack (s);
+
+ for (i = 0; i < 8; i++) {
+ printf("s[%d] = %s\n", i, strv_get(s, i));
+ }
+
+ printf("setting ...\n");
+
+ s = strv_set_ref(s, 1, "Testing 1 x");
+
+ for (i = 0; i < 8; i++) {
+ printf("s[%d] = %s\n", i, strv_get(s, i));
+ }
+
+ printf("packing ...\n");
+ s = strv_pack (s);
+
+ for (i = 0; i < 8; i++) {
+ printf("s[%d] = %s\n", i, strv_get(s, i));
+ }
+
+ strv_free (s);
+
+#if 0
+ time_start("Using memchunks");
+ mc = memchunk_new (CHUNK_COUNT, CHUNK_SIZE);
+ for (i = 0; i < 1000000; i++) {
+ mem = memchunk_alloc (mc);
+ if ((i & 1) == 0)
+ memchunk_free (mc, mem);
+ }
+ s (sleep (10));
+ memchunk_destroy (mc);
+ time_end("allocating 1000000 memchunks, freeing 500k");
+
+ time_start("Using gmemchunks");
+ gmc = g_mem_chunk_new("memchunk", CHUNK_SIZE, CHUNK_SIZE*CHUNK_COUNT, G_ALLOC_AND_FREE);
+ for (i = 0; i < 1000000; i++) {
+ mem = g_mem_chunk_alloc (gmc);
+ if ((i & 1) == 0)
+ g_mem_chunk_free (gmc, mem);
+ }
+ s (sleep (10));
+ g_mem_chunk_destroy (gmc);
+ time_end("allocating 1000000 gmemchunks, freeing 500k");
+
+ time_start("Using memchunks");
+ mc = memchunk_new (CHUNK_COUNT, CHUNK_SIZE);
+ for (i = 0; i < 1000000; i++) {
+ mem = memchunk_alloc (mc);
+ }
+ s (sleep (10));
+ memchunk_destroy (mc);
+ time_end("allocating 1000000 memchunks");
+
+ time_start("Using gmemchunks");
+ gmc = g_mem_chunk_new("memchunk", CHUNK_SIZE, CHUNK_COUNT*CHUNK_SIZE, G_ALLOC_ONLY);
+ for (i = 0; i < 1000000; i++) {
+ mem = g_mem_chunk_alloc (gmc);
+ }
+ s (sleep (10));
+ g_mem_chunk_destroy (gmc);
+ time_end("allocating 1000000 gmemchunks");
+
+ time_start("Using malloc");
+ for (i = 0; i < 1000000; i++) {
+ malloc (CHUNK_SIZE);
+ }
+ time_end("allocating 1000000 malloc");
+#endif
+
+}
+
+#endif
diff --git a/camel/camel-memchunk.h b/camel/camel-memchunk.h
new file mode 100644
index 0000000..3963ff2
--- /dev/null
+++ b/camel/camel-memchunk.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ * Authors: Michael Zucchi <notzed ximian com>
+ * Jacob Berkman <jacob ximian com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#if !defined (__CAMEL_H_INSIDE__) && !defined (CAMEL_COMPILATION)
+#error "Only <camel/camel.h> can be included directly."
+#endif
+
+#ifndef CAMEL_MEMCHUNK_H
+#define CAMEL_MEMCHUNK_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+/* memchunks - allocate/free fixed-size blocks of memory */
+/* this is like gmemchunk, only faster and less overhead (only 4 bytes for every atomcount allocations) */
+typedef struct _CamelMemChunk CamelMemChunk;
+
+CamelMemChunk * camel_memchunk_new (gint atomcount,
+ gint atomsize);
+gpointer camel_memchunk_alloc (CamelMemChunk *memchunk);
+gpointer camel_memchunk_alloc0 (CamelMemChunk *memchunk);
+void camel_memchunk_free (CamelMemChunk *memchunk,
+ gpointer mem);
+void camel_memchunk_empty (CamelMemChunk *memchunk);
+void camel_memchunk_clean (CamelMemChunk *memchunk);
+void camel_memchunk_destroy (CamelMemChunk *memchunk);
+
+G_END_DECLS
+
+#endif /* CAMEL_MEMCHUNK_H */
diff --git a/camel/camel-store-summary.c b/camel/camel-store-summary.c
index 3a1da2d..1c4678e 100644
--- a/camel/camel-store-summary.c
+++ b/camel/camel-store-summary.c
@@ -34,8 +34,6 @@
#include <glib/gstdio.h>
-#include <libedataserver/e-memory.h>
-
#include "camel-file-utils.h"
#include "camel-store-summary.h"
#include "camel-url.h"
@@ -71,7 +69,7 @@ store_summary_finalize (GObject *object)
g_free (summary->summary_path);
if (summary->store_info_chunks != NULL)
- e_memchunk_destroy (summary->store_info_chunks);
+ camel_memchunk_destroy (summary->store_info_chunks);
g_mutex_free (summary->priv->summary_lock);
g_mutex_free (summary->priv->io_lock);
diff --git a/camel/camel-store-summary.h b/camel/camel-store-summary.h
index d0ddb20..01f686e 100644
--- a/camel/camel-store-summary.h
+++ b/camel/camel-store-summary.h
@@ -29,6 +29,7 @@
#include <stdio.h>
#include <camel/camel-enums.h>
+#include <camel/camel-memchunk.h>
#include <camel/camel-mime-parser.h>
#include <camel/camel-object.h>
#include <camel/camel-url.h>
@@ -108,7 +109,7 @@ struct _CamelStoreSummary {
guint32 store_info_size;
/* memory allocators (setup automatically) */
- struct _EMemChunk *store_info_chunks;
+ CamelMemChunk *store_info_chunks;
gchar *summary_path;
diff --git a/camel/camel-trie.c b/camel/camel-trie.c
index acac762..8bc60c3 100644
--- a/camel/camel-trie.c
+++ b/camel/camel-trie.c
@@ -25,8 +25,7 @@
#include <stdio.h>
#include <string.h>
-#include <libedataserver/e-memory.h>
-
+#include "camel-memchunk.h"
#include "camel-trie.h"
#define d(x)
@@ -57,8 +56,8 @@ struct _CamelTrie {
GPtrArray *fail_states;
gboolean icase;
- EMemChunk *match_chunks;
- EMemChunk *state_chunks;
+ CamelMemChunk *match_chunks;
+ CamelMemChunk *state_chunks;
};
static inline gunichar
@@ -130,8 +129,8 @@ camel_trie_new (gboolean icase)
trie->fail_states = g_ptr_array_sized_new (8);
trie->icase = icase;
- trie->match_chunks = e_memchunk_new (8, sizeof (struct _trie_match));
- trie->state_chunks = e_memchunk_new (8, sizeof (struct _trie_state));
+ trie->match_chunks = camel_memchunk_new (8, sizeof (struct _trie_match));
+ trie->state_chunks = camel_memchunk_new (8, sizeof (struct _trie_state));
return trie;
}
@@ -148,8 +147,8 @@ void
camel_trie_free (CamelTrie *trie)
{
g_ptr_array_free (trie->fail_states, TRUE);
- e_memchunk_destroy (trie->match_chunks);
- e_memchunk_destroy (trie->state_chunks);
+ camel_memchunk_destroy (trie->match_chunks);
+ camel_memchunk_destroy (trie->state_chunks);
g_free (trie);
}
@@ -173,12 +172,12 @@ trie_insert (CamelTrie *trie,
{
struct _trie_match *m;
- m = e_memchunk_alloc (trie->match_chunks);
+ m = camel_memchunk_alloc (trie->match_chunks);
m->next = q->match;
m->c = c;
q->match = m;
- q = m->state = e_memchunk_alloc (trie->state_chunks);
+ q = m->state = camel_memchunk_alloc (trie->state_chunks);
q->match = NULL;
q->fail = &trie->root;
q->final = 0;
diff --git a/camel/camel.h b/camel/camel.h
index 44baa86..ab674c7 100644
--- a/camel/camel.h
+++ b/camel/camel.h
@@ -59,6 +59,7 @@
#include <camel/camel-lock-client.h>
#include <camel/camel-lock-helper.h>
#include <camel/camel-medium.h>
+#include <camel/camel-memchunk.h>
#include <camel/camel-mempool.h>
#include <camel/camel-mime-filter.h>
#include <camel/camel-mime-filter-basic.h>
diff --git a/docs/reference/camel/camel-docs.sgml b/docs/reference/camel/camel-docs.sgml
index 621f2d4..9fc32b7 100644
--- a/docs/reference/camel/camel-docs.sgml
+++ b/docs/reference/camel/camel-docs.sgml
@@ -182,6 +182,7 @@
<xi:include href="xml/camel-list-utils.xml"/>
<xi:include href="xml/camel-lock.xml"/>
<xi:include href="xml/camel-lock-client.xml"/>
+ <xi:include href="xml/camel-memchunk.xml"/>
<xi:include href="xml/camel-mempool.xml"/>
<xi:include href="xml/camel-mime-utils.xml"/>
<xi:include href="xml/camel-movemail.xml"/>
@@ -211,6 +212,10 @@
<title>Index of deprecated symbols</title>
<xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
</index>
+ <index id="api-index-3.4" role="3.4">
+ <title>Index of new symbols in 3.4</title>
+ <xi:include href="xml/api-index-3.4.xml"><xi:fallback /></xi:include>
+ </index>
<index id="api-index-3.2" role="3.2">
<title>Index of new symbols in 3.2</title>
<xi:include href="xml/api-index-3.2.xml"><xi:fallback /></xi:include>
diff --git a/docs/reference/camel/camel-sections.txt b/docs/reference/camel/camel-sections.txt
index 0f07fc0..5de1021 100644
--- a/docs/reference/camel/camel-sections.txt
+++ b/docs/reference/camel/camel-sections.txt
@@ -2802,6 +2802,18 @@ camel_unlock_folder
</SECTION>
<SECTION>
+<FILE>camel-memchunk</FILE>
+CamelMemChunk
+camel_memchunk_new
+camel_memchunk_alloc
+camel_memchunk_alloc0
+camel_memchunk_free
+camel_memchunk_empty
+camel_memchunk_clean
+camel_memchunk_destroy
+</SECTION>
+
+<SECTION>
<FILE>camel-mempool</FILE>
CamelMemPool
CamelMemPoolFlags
diff --git a/docs/reference/camel/tmpl/camel-memchunk.sgml b/docs/reference/camel/tmpl/camel-memchunk.sgml
new file mode 100644
index 0000000..1f26740
--- /dev/null
+++ b/docs/reference/camel/tmpl/camel-memchunk.sgml
@@ -0,0 +1,89 @@
+<!-- ##### SECTION Title ##### -->
+camel-memchunk
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### SECTION Image ##### -->
+
+
+<!-- ##### STRUCT CamelMemChunk ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION camel_memchunk_new ##### -->
+<para>
+
+</para>
+
+ atomcount:
+ atomsize:
+ Returns:
+
+
+<!-- ##### FUNCTION camel_memchunk_alloc ##### -->
+<para>
+
+</para>
+
+ memchunk:
+ Returns:
+
+
+<!-- ##### FUNCTION camel_memchunk_alloc0 ##### -->
+<para>
+
+</para>
+
+ memchunk:
+ Returns:
+
+
+<!-- ##### FUNCTION camel_memchunk_free ##### -->
+<para>
+
+</para>
+
+ memchunk:
+ mem:
+
+
+<!-- ##### FUNCTION camel_memchunk_empty ##### -->
+<para>
+
+</para>
+
+ memchunk:
+
+
+<!-- ##### FUNCTION camel_memchunk_clean ##### -->
+<para>
+
+</para>
+
+ memchunk:
+
+
+<!-- ##### FUNCTION camel_memchunk_destroy ##### -->
+<para>
+
+</para>
+
+ memchunk:
+
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]