X-Git-Url: http://git.vrable.net/?a=blobdiff_plain;f=bluesky%2Futil.c;h=d292634731b662827dc8c0dfbeec0f566ab5a32a;hb=8ab9f6acce5bbc6e56d2f3fa1833be06faf46770;hp=3ac6596808bafd865a7a8c7adb97b588c7ea8997;hpb=ebdb5ef23b8e152a4793d5927b5d92d7e7b2cc4f;p=bluesky.git diff --git a/bluesky/util.c b/bluesky/util.c index 3ac6596..d292634 100644 --- a/bluesky/util.c +++ b/bluesky/util.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "bluesky-private.h" @@ -59,6 +60,7 @@ gboolean bluesky_inode_is_ready(BlueSkyInode *inode) BlueSkyRCStr *bluesky_string_new(gpointer data, gsize len) { BlueSkyRCStr *string = g_new(BlueSkyRCStr, 1); + string->mmap = NULL; string->data = data; string->len = len; g_atomic_int_set(&string->refcount, 1); @@ -72,6 +74,21 @@ BlueSkyRCStr *bluesky_string_new_from_gstring(GString *s) return bluesky_string_new(g_string_free(s, FALSE), len); } +/* Create a new BlueSkyRCStr from a memory-mapped buffer. */ +BlueSkyRCStr *bluesky_string_new_from_mmap(BlueSkyCacheFile *mmap, + int offset, gsize len) +{ + g_assert(offset + len <= mmap->len); + + BlueSkyRCStr *string = g_new(BlueSkyRCStr, 1); + string->mmap = mmap; + g_atomic_int_inc(&mmap->mapcount); + string->data = (char *)mmap->addr + offset; + string->len = len; + g_atomic_int_set(&string->refcount, 1); + return string; +} + void bluesky_string_ref(BlueSkyRCStr *string) { if (string == NULL) @@ -86,7 +103,11 @@ void bluesky_string_unref(BlueSkyRCStr *string) return; if (g_atomic_int_dec_and_test(&string->refcount)) { - g_free(string->data); + if (string->mmap == NULL) { + g_free(string->data); + } else { + bluesky_mmap_unref(string->mmap); + } g_free(string); } } @@ -102,6 +123,14 @@ BlueSkyRCStr *bluesky_string_dup(BlueSkyRCStr *string) if (string == NULL) return NULL; + if (string->mmap != NULL) { + BlueSkyRCStr *s; + s = bluesky_string_new(g_memdup(string->data, string->len), + string->len); + bluesky_string_unref(string); + return s; + } + if (g_atomic_int_dec_and_test(&string->refcount)) { /* There are no other shared copies, so return this one. */ g_atomic_int_inc(&string->refcount); @@ -119,6 +148,8 @@ BlueSkyRCStr *bluesky_string_dup(BlueSkyRCStr *string) * if needed). */ void bluesky_string_resize(BlueSkyRCStr *string, gsize len) { + g_assert(string->mmap == NULL); + if (string->len == len) return;