evas/cserve2: Repack File_Data shared array
authorJean-Philippe Andre <jp.andre@samsung.com>
Tue, 23 Jul 2013 10:30:54 +0000 (19:30 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Mon, 28 Oct 2013 06:47:13 +0000 (15:47 +0900)
src/bin/evas/evas_cserve2.h
src/bin/evas/evas_cserve2_cache.c
src/bin/evas/evas_cserve2_index.c

index b6bdff3..361d08a 100644 (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,
index d3926e2..8624c08 100644 (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);
index b79c2f8..fd95aa5 100644 (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