diff options
Diffstat (limited to 'src/analysis')
| -rw-r--r-- | src/analysis/binary.c | 56 | ||||
| -rw-r--r-- | src/analysis/binary.h | 8 | ||||
| -rw-r--r-- | src/analysis/db/collection.c | 145 | ||||
| -rw-r--r-- | src/analysis/db/collection.h | 12 | ||||
| -rw-r--r-- | src/analysis/db/item-int.h | 2 | ||||
| -rw-r--r-- | src/analysis/db/item.c | 26 | 
6 files changed, 214 insertions, 35 deletions
| diff --git a/src/analysis/binary.c b/src/analysis/binary.c index c6ae4e5..615e72e 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -862,6 +862,62 @@ bool _g_loaded_binary_add_to_collection(GLoadedBinary *binary, DBFeatures featur +/****************************************************************************** +*                                                                             * +*  Paramètres  : binary  = élément binaire à consulter.                       * +*                feature = fonctionnalité visée par la requête.               * +*                item    = élémnent à retirer d'un serveur de collection.     * +*                lock    = indique si le verrou d'écriture doit être posé.    * +*                                                                             * +*  Description : Demande la suppression de modification dans une collection.  * +*                                                                             * +*  Retour      : Bilan partiel de l'opération demandée.                       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool _g_loaded_binary_remove_from_collection(GLoadedBinary *binary, DBFeatures feature, GDbItem *item, bool lock) +{ +    bool result;                            /* Bilan à faire remonter      */ +    GDbCollection *collec;                  /* Collection visée au final   */ +    DBStorage storage;                      /* Forme d'enregistrement      */ +    GDbClient *client;                      /* Liaison à utiliser          */ +    int fd;                                 /* Identifiant du canal de com.*/ + +    collec = g_loaded_binary_find_collection(binary, feature); +    if (collec == NULL) return false; + +    /* S'il n'y a pas besoin de sauvegarde... */ +    if (g_db_item_is_volatile(item)) +        _g_db_collection_remove_item(collec, item, lock); + +    /* Sinon on envoie par le réseau ! */ +    else +    { +        storage = g_loaded_binary_get_storage(binary, feature); + + +        /* TODO : sélection du bon client... */ +        client = binary->local; + + +        fd = g_db_client_get_fd(client); + +        result = g_db_collection_send(collec, fd, DBA_REM_ITEM, item); + +        g_db_client_put_fd(client); + +    } + +    g_object_unref(G_OBJECT(collec)); + +    return result; + +} + + + diff --git a/src/analysis/binary.h b/src/analysis/binary.h index fb37310..768f53a 100644 --- a/src/analysis/binary.h +++ b/src/analysis/binary.h @@ -128,13 +128,15 @@ GDbCollection *g_loaded_binary_find_collection(const GLoadedBinary *, DBFeatures  bool _g_loaded_binary_add_to_collection(GLoadedBinary *, DBFeatures, GDbItem *, bool);  #define g_loaded_binary_add_to_collection(b, f, i) \ -    _g_loaded_binary_add_to_collection(b, f, i, true); +    _g_loaded_binary_add_to_collection(b, f, i, true) +/* Demande la suppression de modification dans une collection. */ +bool _g_loaded_binary_remove_from_collection(GLoadedBinary *, DBFeatures, GDbItem *, bool); +#define g_loaded_binary_remove_from_collection(b, f, i) \ +    _g_loaded_binary_remove_from_collection(b, f, i, true) -#define g_loaded_binary_remove_from_collection(b, f, i) -  /**   * TODO : diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c index 5e5adb7..0292c5c 100644 --- a/src/analysis/db/collection.c +++ b/src/analysis/db/collection.c @@ -278,6 +278,8 @@ bool g_db_collection_recv(GDbCollection *collec, int fd, sqlite3 *db)      bool status;                            /* Bilan de lecture initiale   */      DBAction action;                        /* Commande de la requête      */      GDbItem *item;                          /* Définition d'élément visé   */ +    GList *found;                           /* Test de présence existante  */ +    timestamp_t inactive;                   /* Horodatage de désactivation */      status = safe_recv(fd, &val32, sizeof(uint32_t), 0);      if (!status) return false; @@ -287,9 +289,6 @@ bool g_db_collection_recv(GDbCollection *collec, int fd, sqlite3 *db)      item = g_object_new(collec->type, NULL); -    if (db != NULL) -        g_db_item_set_server_side(item); -      status = g_db_item_recv(item, fd, 0);      if (!status) return false; @@ -299,6 +298,10 @@ bool g_db_collection_recv(GDbCollection *collec, int fd, sqlite3 *db)      {          case DBA_ADD_ITEM: +            /* Ecrasement des horodatages par les valeurs communes du serveur */ +            if (db != NULL) +                g_db_item_set_server_side(item); +              result = g_db_collection_add_item(collec, item);              if (result) @@ -310,17 +313,44 @@ bool g_db_collection_recv(GDbCollection *collec, int fd, sqlite3 *db)              }              if (!result) -                /* TODO : retirer l'élémnt */; +                /* TODO : retirer l'élément */;              break;          case DBA_REM_ITEM: + +            g_db_collection_wlock(collec); + +            found = g_list_find_custom(collec->items, item, (GCompareFunc)g_db_item_compare_with_timestamp); + +            result = (found != NULL); + +            if (result) +            { +                /* Côté client */ +                if (db == NULL) +                    result = _g_db_collection_remove_item(collec, item, false); + +                /* Côté serveur */ +                else +                { +                    if (g_db_item_is_active(G_DB_ITEM(found->data))) +                    { +                        inactive = _g_db_collection_compute_inactivity_timestamp(collec, false); +                        result = _g_db_collection_update_item_activity(collec, item, inactive, false); +                    } +                } + +            } + +            g_db_collection_wunlock(collec); +              break;          case DBA_CHANGE_STATE:              if (db == NULL) -                result = g_db_collection_update_item_activity(collec, item); +                result = g_db_collection_update_item_activity(collec, item, g_db_item_get_timestamp(item) + 1);              else                  result = false; @@ -565,9 +595,104 @@ bool _g_db_collection_add_item(GDbCollection *collec, GDbItem *item, bool lock)      g_signal_emit_by_name(collec, "content-changed", DBA_ADD_ITEM, item); +    if (lock) +        g_db_collection_wunlock(collec); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : collec = ensemble d'éléments à considérer.                   * +*                item   = élément de collection à manipuler.                  * +*                lock   = indique si le verrou d'écriture doit être posé.     * +*                                                                             * +*  Description : Procède au retrait d'un nouvel élément dans la collection.   * +*                                                                             * +*  Retour      : Bilan de l'exécution de l'opération.                         * +*                                                                             * +*  Remarques   : L'appelant reste le propriétaire de l'object transféré.      * +*                                                                             * +******************************************************************************/ + +bool _g_db_collection_remove_item(GDbCollection *collec, GDbItem *item, bool lock) +{ +    bool result;                            /* Bilan à faire remonter      */ +    GList *found;                           /* Test de présence existante  */ +    GDbItem *internal;                      /* Elément interne à modifier  */ + +    result = true; + +    if (lock) +        g_db_collection_wlock(collec); + +    found = g_list_find_custom(collec->items, item, (GCompareFunc)g_db_item_compare_with_timestamp); + +    result = (found != NULL); + +    if (result) +    { +        internal = G_DB_ITEM(found->data); + +        collec->items = g_list_delete_link(collec->items, found); + +        g_signal_emit_by_name(collec, "content-changed", DBA_REM_ITEM, internal); + +        g_object_unref(G_OBJECT(internal)); + +    } + +    if (lock) +        g_db_collection_wunlock(collec); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : collec = ensemble d'éléments à considérer.                   * +*                lock   = indique si le verrou d'écriture doit être posé.     * +*                                                                             * +*  Description : Détermine l'horodatage le plus jeune pour une désactivation. * +*                                                                             * +*  Retour      : Horodatage à utiliser pour une phase de désactivation.       * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +timestamp_t _g_db_collection_compute_inactivity_timestamp(GDbCollection *collec, bool lock) +{ +    timestamp_t result;                     /* Horodatage à retourner      */ +    GList *iter;                            /* Boucle de parcours          */ +    GDbItem *item;                          /* Elément interne à consulter */ +    timestamp_t stamp;                      /* Horodatage de l'élément     */ + +    result = TIMESTAMP_ALL_ACTIVE; + +    if (lock) +        g_db_collection_wlock(collec); + +    for (iter = g_list_first(collec->items); +         iter != NULL && result; +         iter = g_list_next(iter)) +    { +        item = G_DB_ITEM(iter->data); + +        if (!g_db_item_is_active(item)) +        { +            stamp = g_db_item_get_timestamp(item); -    printf(" ==== CONTENT CHANGED (-> %u) !!!\n", g_list_length(collec->items)); +            if (timestamp_is_younger(stamp, result)) +                result = stamp; +        } + +    }      if (lock)          g_db_collection_wunlock(collec); @@ -591,7 +716,7 @@ bool _g_db_collection_add_item(GDbCollection *collec, GDbItem *item, bool lock)  *                                                                             *  ******************************************************************************/ -bool _g_db_collection_update_item_activity(GDbCollection *collec, GDbItem *item, bool lock) +bool _g_db_collection_update_item_activity(GDbCollection *collec, GDbItem *item, timestamp_t timestamp, bool lock)  {      bool result;                            /* Bilan à faire remonter      */      GList *found;                           /* Test de présence existante  */ @@ -608,7 +733,7 @@ bool _g_db_collection_update_item_activity(GDbCollection *collec, GDbItem *item,      {          internal = G_DB_ITEM(found->data); -        g_db_item_set_activity(internal, (timestamp_t []) { g_db_item_get_timestamp(item) + 1 }); +        g_db_item_set_activity(internal, (timestamp_t []) { timestamp });          g_signal_emit_by_name(collec, "content-changed", DBA_CHANGE_STATE, internal); @@ -893,8 +1018,6 @@ bool g_db_collection_load_all_items(GDbCollection *collec, sqlite3 *db)          new = g_object_new(G_DB_COLLECTION(collec)->type, NULL); -        g_db_item_set_server_side(new); -          result = g_db_item_load(new, values, count);          result &= g_db_collection_add_item(G_DB_COLLECTION(collec), new); @@ -1321,6 +1444,8 @@ bool update_activity_in_collections(GList *list, int fd, sqlite3 *db)      GList *i;                               /* Boucle de parcours #2       */      GDbItem *item;                          /* Elément collecté à manipuler*/ +    /* TODO : lock ? */ +      status = recv_timestamp(×tamp, fd, 0);      if (!status) return false; diff --git a/src/analysis/db/collection.h b/src/analysis/db/collection.h index ac3e60f..e9f93d2 100644 --- a/src/analysis/db/collection.h +++ b/src/analysis/db/collection.h @@ -102,11 +102,19 @@ bool g_db_collection_has_item(GDbCollection *, GDbItem *);  /* Procède à l'ajout d'un nouvel élément dans la collection. */  bool _g_db_collection_add_item(GDbCollection *, GDbItem *, bool); +/* Procède au retrait d'un nouvel élément dans la collection. */ +bool _g_db_collection_remove_item(GDbCollection *, GDbItem *, bool); + +/* Détermine l'horodatage le plus jeune pour une désactivation. */ +timestamp_t _g_db_collection_compute_inactivity_timestamp(GDbCollection *, bool); +  /* Met à jour le statut d'activité d'un élément de collection. */ -bool _g_db_collection_update_item_activity(GDbCollection *, GDbItem *, bool); +bool _g_db_collection_update_item_activity(GDbCollection *, GDbItem *, timestamp_t, bool);  #define g_db_collection_add_item(c, i) _g_db_collection_add_item(c, i, true) -#define g_db_collection_update_item_activity(c, i) _g_db_collection_update_item_activity(c, i, true) +#define g_db_collection_remove_item(c, i) _g_db_collection_remove_item(c, i, true) +#define g_db_collection_compute_inactivity_timestamp(c) _g_db_collection_compute_inactivity_timestamp(c, true) +#define g_db_collection_update_item_activity(c, i, t) _g_db_collection_update_item_activity(c, i, t, true)  /* Active les éléments en amont d'un horodatage donné. */  GList *g_db_collection_set_last_active(GDbCollection *, timestamp_t, timestamp_t *, sqlite3 *); diff --git a/src/analysis/db/item-int.h b/src/analysis/db/item-int.h index 1af1048..fb33c72 100644 --- a/src/analysis/db/item-int.h +++ b/src/analysis/db/item-int.h @@ -63,8 +63,6 @@ struct _GDbItem  {      GObject parent;                         /* A laisser en premier        */ -    bool server_side;                       /* Instance côté serveur       */ -      timestamp_t created;                    /* Date de création            */      timestamp_t timestamp;                  /* Date dernière activité      */ diff --git a/src/analysis/db/item.c b/src/analysis/db/item.c index 5463e85..3fc6f6f 100644 --- a/src/analysis/db/item.c +++ b/src/analysis/db/item.c @@ -191,8 +191,6 @@ void g_db_item_set_server_side(GDbItem *item)      init_timestamp(&item->created);      item->timestamp = item->created; -    item->server_side = true; -  } @@ -288,15 +286,11 @@ static bool g_db_item_recv_from_fd(GDbItem *item, int fd, int flags)  {      bool status;                            /* Bilan d'une réception       */ -    if (!item->server_side) -    { -        status = recv_timestamp(&item->created, fd, flags); -        if (!status) return false; - -        status = recv_timestamp(&item->timestamp, fd, flags); -        if (!status) return false; +    status = recv_timestamp(&item->created, fd, flags); +    if (!status) return false; -    } +    status = recv_timestamp(&item->timestamp, fd, flags); +    if (!status) return false;      status = recv_rle_string(&item->author, fd, flags);      if (!status) return false; @@ -354,15 +348,11 @@ static bool g_db_item_send_to_fd(const GDbItem *item, int fd, int flags)  {      bool status;                            /* Bilan d'une émission        */ -    if (item->server_side) -    { -        status = send_timestamp(&item->created, fd, MSG_MORE | flags); -        if (!status) return false; - -        status = send_timestamp(&item->timestamp, fd, MSG_MORE | flags); -        if (!status) return false; +    status = send_timestamp(&item->created, fd, MSG_MORE | flags); +    if (!status) return false; -    } +    status = send_timestamp(&item->timestamp, fd, MSG_MORE | flags); +    if (!status) return false;      status = send_rle_string(&item->author, fd, MSG_MORE | flags);      if (!status) return false; | 
