Propagazione dello stato (dal basso verso l'alto) nell'albero a più passi

4

Uso della rappresentazione Tree (menzionata sotto),

typedef enum {Running, Warning, Critical}Status;

struct TreeNode;

typedef struct List{
  int childCount;
  struct treeNode **childList;
}List;

typedef struct Resource{
  char *resourceName;
  Status resourceStatus;
}Resource;

typedef struct treeNode{
  struct treeNode *parent;
  Resource *ITInfraResource;
  List *childList;
}Node;

typedef struct MultiWalkTree{
  Node *root;
  int size;
}Tree;

Considera l'albero sotto costruito,

in cui il valore resourceStatus dei nodi di Livello 1 viene aggiornato in base al valore resourceStatus dei figli immediati.

Esempio: se resourceStatus membro di Memory nodo sotto Router-1 nodo diventa Critical allora resourceStatus in Router-1 nodo dovrebbe anche mostrare lo stesso valore di stato. resourceStatus dovrebbe propagarsi ulteriormente al nodo root

La mia domanda:

Supponendo che resourceStatus nei nodi foglia venga aggiornato frequentemente (utilizzando il protocollo SNMP, ad esempio), Uso di C,

Quale dovrebbe essere l'approccio per rendere Tree intelligente che aggiorni automaticamente il suo nodo genitore resourceStatus al cambio di stato dei suoi figli?

Nota: stavo pensando alle funzioni di callback, ma ancora per avere un'idea chiara

    
posta overexchange 17.12.2016 - 05:03
fonte

1 risposta

2

Con C, la struttura dei dati è e rimarrà stupida. Questo non è un giudizio di valore: intendo che se qualche codice ha l'indirizzo di treeNode *x , può cambiare x->ITInfraResource->resourceStatus senza che accada altro.

Incapsula dati

Per controllare questa situazione e rendere la tua struttura intelligente, devi prima incapsulare la tua struttura, in modo tale che il codice usando deve sempre usare alcune delle tue funzioni per cambiare lo stato.

In pratica, ci sono diversi modi per raggiungere questo obiettivo. Ad esempio, è possibile modulare la struttura utilizzando una compilazione separata. Nelle intestazioni useresti solo una dichiarazione in avanti della tua struttura Resource . Ciò consente al codice che utilizza di utilizzare i puntatori a una risorsa, ma vieta di accedere direttamente ai suoi contenuti:

typedef struct Resource Resource;   

void change_resource_status (treeNode *n, Status s);  // must use to access content

E nell'unità di compilazione in cui verranno implementate change_resource_status() e funzioni simili, potresti definire la struttura, mantenendola privata per il mondo esterno:

struct Resource {
  char *resourceName;
  Status resourceStatus;
}; 

Hai quindi il controllo di tutte le modifiche apportate e puoi propagare la modifica nella struttura utilizzando vari approcci

Strategie di propagazione

Se fossi in un design orientato agli oggetti, ti consiglierei forse un osservatore modello o un ciclo degli eventi utilizzando un comando modello. Ma in un mondo non-object, per una tale struttura ad albero raccomanderei definitivamente un approccio più semplice che non richiede l'uso di puntatori di funzione e funzioni di callback.

In base all'incapsulamento, il modo più semplice sarebbe iterare attraverso i nodi parent per aggiornarli direttamente o chiamando una funzione per ricalcolarli.

Due tecniche potrebbero minimizzare i ricalcoli:

  • ricalcolo condizionale: ad esempio, se il genitore deve essere aggiornato con lo stato massimo dei figli, allora il genitore deve essere aggiornato solo se il nuovo stato dei figli è superiore a quello vecchio (o se lo stato dei figli precedenti corrisponde al valore massimo del genitore).

  • ricalcolo asincrono: per qualsiasi modifica, è possibile impostare un flag dirty nel nodo che viene modificato e i nodi che devono essere ricalcolati. In una seconda fase, quando tutte le modifiche sono state apportate, o periodicamente, si passa attraverso l'albero e si ricalcolano tutti i nodi sporchi.

Se non puoi scegliere l'incapsulamento

Un modo per gestire le modifiche sarebbe quindi avere un secondo stato "ombra".

Ogni tanto (ad esempio utilizzando un approccio multi-threading?), un algoritmo di ricalcolo può esplorare i nodi in cui lo stato è diverso dallo stato dell'ombra (cioè i nodi "sporchi") e avviare il processo di ricalcolo.

Ma senza un'appropriata incapsulamento, l'algoritmo di ricalcolo rimarrebbe vulnerabile all'abuso dello stato dell'ombra.

    
risposta data 17.12.2016 - 16:04
fonte