summaryrefslogtreecommitdiff
path: root/src/arch/sharing/manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/sharing/manager.c')
-rw-r--r--src/arch/sharing/manager.c100
1 files changed, 46 insertions, 54 deletions
diff --git a/src/arch/sharing/manager.c b/src/arch/sharing/manager.c
index 2e92766..4c60e72 100644
--- a/src/arch/sharing/manager.c
+++ b/src/arch/sharing/manager.c
@@ -25,9 +25,14 @@
#include <assert.h>
+#include <malloc.h>
#ifdef DEBUG_DUMP_STATS
# include <stdio.h>
#endif
+#include <string.h>
+
+
+#include "../../common/sort.h"
@@ -36,7 +41,8 @@ struct _GShareManager
{
GObject parent; /* A laisser en premier */
- GHashTable *table; /* Collection de partages */
+ GSharedInstance **instances; /* Instances partagées */
+ size_t count; /* Quantité de ces instances */
GMutex access; /* Accès à la table */
GType managed; /* Type d'instances gérées */
@@ -107,6 +113,9 @@ static void g_share_manager_class_init(GShareManagerClass *class)
static void g_share_manager_init(GShareManager *manager)
{
+ manager->instances = NULL;
+ manager->count = 0;
+
g_mutex_init(&manager->access);
}
@@ -126,7 +135,11 @@ static void g_share_manager_init(GShareManager *manager)
static void g_share_manager_dispose(GShareManager *manager)
{
- g_hash_table_unref(manager->table);
+ size_t i; /* Boucle de parcours */
+
+ for (i = 0; i < manager->count; i++)
+ g_object_unref(G_OBJECT(manager->instances[i]));
+
g_mutex_clear(&manager->access);
G_OBJECT_CLASS(g_share_manager_parent_class)->dispose(G_OBJECT(manager));
@@ -148,6 +161,9 @@ static void g_share_manager_dispose(GShareManager *manager)
static void g_share_manager_finalize(GShareManager *manager)
{
+ if (manager->instances != NULL)
+ free(manager->instances);
+
G_OBJECT_CLASS(g_share_manager_parent_class)->finalize(G_OBJECT(manager));
}
@@ -171,11 +187,6 @@ GShareManager *g_share_manager_new(GType type)
result = g_object_new(G_TYPE_SHARE_MANAGER, NULL);
- result->table = g_hash_table_new_full((GHashFunc)g_direct_hash,
- (GEqualFunc)g_shared_instance_is_equal,
- (GDestroyNotify)g_object_unref,
- (GDestroyNotify)NULL);
-
result->managed = type;
return result;
@@ -185,8 +196,8 @@ GShareManager *g_share_manager_new(GType type)
/******************************************************************************
* *
-* Paramètres : manager = gestionnaire d'instance à consulter. *
-* info = informations à retrouver intégralement. *
+* Paramètres : manager = gestionnaire d'instance à consulter. *
+* template = informations à retrouver intégralement. *
* *
* Description : Retrouve ou crée une instance partagée. *
* *
@@ -196,29 +207,23 @@ GShareManager *g_share_manager_new(GType type)
* *
******************************************************************************/
-GSharedInstance *g_share_manager_get(GShareManager *manager, const void *info)
+GSharedInstance *g_share_manager_get(GShareManager *manager, GSharedInstance *template)
{
GSharedInstance *result; /* Trouvaille à retourner */
- gpointer found; /* Elément correspondant ? */
+ size_t index; /* Indice d'une instance idéale*/
+ bool found; /* Existence de cette instance */
bool status; /* Conclusion d'initialisation */
-#ifndef NDEBUG
- gboolean new; /* Présence de partage existant*/
-#endif
-
- gboolean find_shared_matching_info(const GSharedInstance *key, gpointer unused, const void *nfo)
- {
- return g_shared_instance_compare_info(key, nfo);
- }
g_mutex_lock(&manager->access);
- found = g_hash_table_find(manager->table, (GHRFunc)find_shared_matching_info, (void *)info);
+ found = bsearch_index(&template, manager->instances, manager->count, sizeof(GSharedInstance *),
+ (__compar_fn_t)g_shared_instance_quickly_compare, &index);
- if (found == NULL)
+ if (!found)
{
result = g_object_new(manager->managed, NULL);
- status = g_shared_instance_init(result, info);
+ status = g_shared_instance_init(result, template);
if (!status)
{
@@ -230,19 +235,15 @@ GSharedInstance *g_share_manager_get(GShareManager *manager, const void *info)
{
g_shared_instance_inc_references(result);
-#ifndef NDEBUG
- new = g_hash_table_add(manager->table, result);
- assert(new);
-#else
- g_hash_table_add(manager->table, result);
-#endif
+ manager->instances = (GSharedInstance **)_qinsert(manager->instances, &manager->count,
+ sizeof(GSharedInstance *), &result, index);
}
}
else
- result = G_SHARED_INSTANCE(found);
+ result = manager->instances[index];
if (result != NULL)
{
@@ -261,7 +262,7 @@ GSharedInstance *g_share_manager_get(GShareManager *manager, const void *info)
* *
* Paramètres : manager = gestionnaire d'instance à consulter. *
* old = ancienne instance partagée à faire évoluer. *
-* info = informations à retrouver intégralement. *
+* template = informations à retrouver intégralement. *
* container = propriétaire de l'ancienne version à contacter. *
* *
* Description : Met à jour une instance partagée. *
@@ -272,11 +273,11 @@ GSharedInstance *g_share_manager_get(GShareManager *manager, const void *info)
* *
******************************************************************************/
-GSharedInstance *g_share_manager_update(GShareManager *manager, GSharedInstance *old, const void *info, GShareContainer *container)
+GSharedInstance *g_share_manager_update(GShareManager *manager, GSharedInstance *old, GSharedInstance *template, GShareContainer *container)
{
GSharedInstance *result; /* Nouvelle instance à renvoyer*/
- result = g_share_manager_get(manager, info);
+ result = g_share_manager_get(manager, template);
if (container != NULL)
g_share_container_replace(container, old, result);
@@ -303,22 +304,19 @@ GSharedInstance *g_share_manager_update(GShareManager *manager, GSharedInstance
void g_share_manager_put(GShareManager *manager, GSharedInstance *shared)
{
-#ifndef NDEBUG
- gboolean found; /* Présence de partage existant*/
-#endif
-
g_mutex_lock(&manager->access);
g_shared_instance_dec_references(shared);
if (g_shared_instance_get_references(shared) == 1)
{
-#ifndef NDEBUG
- found = g_hash_table_remove(manager->table, shared);
- assert(found);
-#else
- g_hash_table_remove(manager->table, shared);
-#endif
+ g_object_unref(G_OBJECT(shared));
+
+ manager->instances = (GSharedInstance **)qdelete(manager->instances, &manager->count,
+ sizeof(GSharedInstance *),
+ (__compar_fn_t)g_shared_instance_quickly_compare,
+ &shared);
+
}
g_mutex_unlock(&manager->access);
@@ -341,32 +339,26 @@ void g_share_manager_put(GShareManager *manager, GSharedInstance *shared)
void g_share_manager_dump_stats(GShareManager *manager)
{
unsigned int counter; /* Quantité nécessaire */
+ size_t i; /* Boucle de parcours */
GTypeQuery query; /* Informations sur un type */
- guint size; /* Taille de la table */
-
- void count_shared_instances(const GSharedInstance *key, gpointer unused, unsigned int *c)
- {
- *c += g_shared_instance_get_references(key);
- }
counter = 0;
g_mutex_lock(&manager->access);
- g_hash_table_foreach(manager->table, (GHFunc)count_shared_instances, &counter);
-
- size = g_hash_table_size(manager->table);
+ for (i = 0; i < manager->count; i++)
+ counter += g_shared_instance_get_references(manager->instances[i]);
g_mutex_unlock(&manager->access);
g_type_query(manager->managed, &query);
- printf("%s: current = %u / %u - needed = %u / %u (size=%u, saved=%u)\n",
+ printf("%s: current = %zu / %zu - needed = %u / %u (size=%u, saved=%zu)\n",
query.type_name,
- size, size * query.instance_size,
+ manager->count, manager->count * query.instance_size,
counter, counter * query.instance_size,
query.instance_size,
- (counter - size) * query.instance_size);
+ (counter - manager->count) * query.instance_size);
}
#endif