evas/cserve2: Repack File_Data shared array

This commit is contained in:
Jean-Philippe Andre 2013-07-23 19:30:54 +09:00
parent acae35b4d1
commit d0e647fee3
3 changed files with 60 additions and 17 deletions

View File

@ -322,7 +322,9 @@ void cserve2_shared_index_shutdown(void);
typedef struct _Shared_Array Shared_Array;
typedef struct _Shared_Mempool Shared_Mempool;
typedef Eina_Bool (* Shared_Array_Repack_Skip_Cb) (Shared_Array *, const void *);
typedef Eina_Bool (* Shared_Array_Repack_Skip_Cb) (Shared_Array *sa,
const void *elem,
void *user_data);
// Shared arrays (arrays of fixed size object)
Shared_Array *cserve2_shared_array_new(int tag, int elemsize, int initcount);
@ -337,7 +339,7 @@ int cserve2_shared_array_item_new(Shared_Array *sa);
void *cserve2_shared_array_item_data_get(Shared_Array *sa, int elemid);
Shared_Array *cserve2_shared_array_repack(Shared_Array *sa,
Shared_Array_Repack_Skip_Cb skip,
Eina_Compare_Cb cmp);
Eina_Compare_Cb cmp, void *user_data);
int cserve2_shared_array_item_find(Shared_Array *sa, void *data,
Eina_Compare_Cb cmp);
void *cserve2_shared_array_item_data_find(Shared_Array *sa, void *data,

View File

@ -175,6 +175,8 @@ struct _File_Watch {
};
static unsigned int _entry_id = 0;
static unsigned int _freed_entry_count = 0;
static Shared_Array *_file_data_array = NULL;
static Eina_Hash *file_ids = NULL; // maps path + key --> file_id
@ -242,7 +244,7 @@ _entry_load_reused(Entry *e)
static int
_shm_object_id_find_cb(const void *data1, const void *data2)
_shm_object_id_cmp_cb(const void *data1, const void *data2)
{
const Shm_Object *obj;
unsigned int key;
@ -266,12 +268,14 @@ _file_data_find(unsigned int file_id)
File_Data *fd;
fd = cserve2_shared_array_item_data_find(_file_data_array, &file_id,
_shm_object_id_find_cb);
_shm_object_id_cmp_cb);
if (fd && !fd->refcount)
{
ERR("Can not access object %u with refcount 0", file_id);
return NULL;
}
else if (!fd)
ERR("Could not find file %u", file_id);
return fd;
}
@ -287,6 +291,45 @@ _file_entry_find(unsigned int entry_id)
return (File_Entry *) e;
}
static Eina_Bool
_repack_skip_cb(Shared_Array *sa EINA_UNUSED, const void *elem,
void *user_data EINA_UNUSED)
{
const File_Data *fd = elem;
return (!fd->refcount);
}
static void
_repack()
{
Shared_Array *sa;
int count;
count = cserve2_shared_array_size_get(_file_data_array);
if (count <= 0) return;
// Repack when we have 10% fragmentation over the whole shm buffer
if (_freed_entry_count > 100 ||
((_freed_entry_count * 100) / count >= 10))
{
DBG("Repacking file data array: %s",
cserve2_shared_array_name_get(_file_data_array));
sa = cserve2_shared_array_repack(_file_data_array,
_repack_skip_cb,
_shm_object_id_cmp_cb, NULL);
if (!sa)
{
ERR("Failed to repack array. Keeping previous references!");
return;
}
cserve2_shared_array_del(_file_data_array);
_freed_entry_count = 0;
_file_data_array = sa;
}
}
static Msg_Opened *
_image_opened_msg_create(File_Data *fd, int *size)
@ -845,8 +888,11 @@ _hash_file_entry_free(void *data)
fd = _file_data_find(ASENTRY(fentry)->id);
_file_id_free(fd);
_file_entry_free(fentry);
_file_data_free(fd);
_file_entry_free(fentry);
_freed_entry_count++;
_repack();
}
static void
@ -1097,12 +1143,8 @@ _entry_reference_del(Entry *entry, Reference *ref)
if (fd)
{
if (fd->invalid)
{
_file_entry_free(fentry);
_file_data_free(fd);
}
else if (!fentry->images)
// FIXME: Check difference with master (2 cases vs. only one)
if (fd->invalid || !fentry->images)
eina_hash_del_by_key(file_entries, &entry->id);
}
else
@ -1306,10 +1348,7 @@ _file_changed_cb(const char *path EINA_UNUSED, Eina_Bool deleted EINA_UNUSED, vo
ASENTRY(fentry)->request = NULL;
}
if (!fentry->images && !ASENTRY(fentry)->references)
{
_file_entry_free(fentry);
_file_data_free(fd);
}
_hash_file_entry_free(fentry);
}
eina_hash_del_by_key(file_watch, fw->path);

View File

@ -406,7 +406,8 @@ cserve2_shared_array_foreach(Shared_Array *sa, Eina_Each_Cb cb, void *data)
Shared_Array *
cserve2_shared_array_repack(Shared_Array *sa,
Shared_Array_Repack_Skip_Cb skip,
Eina_Compare_Cb cmp)
Eina_Compare_Cb cmp,
void *user_data)
{
Eina_List *l = NULL;
Shared_Array *sa2;
@ -422,7 +423,7 @@ cserve2_shared_array_repack(Shared_Array *sa,
for (k = 0; k < sa->header->emptyidx; k++)
{
const char *data = srcdata + k * elemsize;
if (skip(sa, data)) continue;
if (skip(sa, data, user_data)) continue;
l = eina_list_sorted_insert(l, cmp, data);
newcount++;
}
@ -443,6 +444,7 @@ cserve2_shared_array_repack(Shared_Array *sa,
const char *data = eina_list_data_get(l);
l = eina_list_remove_list(l, l);
memcpy(dstdata, data, elemsize);
dstdata += elemsize;
}
// Finalize & return