Successivo: , Precedente: , Su: Accedere alla tabella simboli   [Contenuti][Indice]


17.4.10.2 Accedere alle variabili per “cookie” e aggiornarle

Uno scalar cookie è un puntatore nascosto (opaque handle) che fornisce accesso a una variabile globale o a un vettore. Si tratta di un’ottimizzazione, per evitare di ricercare variabili nella Tabella dei simboli di gawk ogni volta che un accesso è necessario. Questo argomento è già stato trattato in precedenza, nella I tipi di dati di impiego generale.

Le funzioni seguenti servono per gestire gli scalar cookie:

awk_bool_t sym_lookup_scalar(awk_scalar_t cookie,
                             awk_valtype_t wanted,
                             awk_value_t *risultato);

Ottiene il valore corrente di uno scalar cookie. Una volta ottenuto lo scalar cookie usando sym_lookup(), si può usare questa funzione per accedere al valore della variabile in modo più efficiente. Restituisce false se il valore non è disponibile.

awk_bool_t sym_update_scalar(awk_scalar_t cookie, awk_value_t *valore);

Aggiorna il valore associato con uno scalar cookie. Restituisce false se il nuovo valore non è del tipo AWK_STRING, AWK_STRNUM, AWK_REGEX o AWK_NUMBER. Anche in questo caso, le variabili predefinite non possono essere aggiornate.

Non è immediatamente evidente come si lavora con gli scalar cookie o quale sia la loro vera ragion d’essere. In teoria, le routine sym_lookup() e sym_update() sono tutto ciò che occorre per lavorare con le variabili. Per esempio, ci potrebbe essere un codice che ricerca il valore di una variabile, valuta una condizione, e potrebbe poi cambiare il valore della variabile a seconda dei risultati della valutazione in modo simile a questo:

/*  do_magic --- fai qualcosa di veramente grande */

static awk_value_t *
do_magic(int nargs, awk_value_t *risultato)
{
    awk_value_t valore;

    if (   sym_lookup("MAGIC_VAR", AWK_NUMBER, & valore)
        && qualche_condizione(valore.num_valore)) {
            valore.num_valore += 42;
            sym_update("MAGIC_VAR", & valore);
    }

    return make_number(0.0, risultato);
}

Questo codice sembra (ed è) semplice e immediato. Qual è il problema?

Beh, si consideri cosa succede se un qualche codice a livello di awk associato con l’estensione richiama la funzione magic() (implementata in linguaggio C da do_magic()), una volta per ogni record, mentre si stanno elaborando file contenenti migliaia o milioni di record. La variabile MAGIC_VAR viene ricercata nella Tabella dei simboli una o due volte per ogni richiamo della funzione!

La ricerca all’interno della Tabella dei simboli è in realtà una pura perdita di tempo; è molto più efficiente ottenere un value cookie che rappresenta la variabile, e usarlo per ottenere il valore della variabile e aggiornarlo a seconda della necessità.111

Quindi, la maniera per usare i valori-cookie è la seguente. Per prima cosa, la variabile di estensione va messa nella Tabella dei simboli di gawk usando sym_update(), come al solito. Poi si deve ottenere uno scalar cookie per la variabile usando sym_lookup():

static awk_scalar_t magic_var_cookie;    /* cookie per MAGIC_VAR */

static void
inizializza_estensione()
{
    awk_value_t valore;

    /* immettere il valore iniziale */
    sym_update("MAGIC_VAR", make_number(42.0, & valore));

    /* ottenere il value cookie */
    sym_lookup("MAGIC_VAR", AWK_SCALAR, & valore);

    /* salvarlo per dopo */
    magic_var_cookie = valore.scalar_cookie;
    …
}

Dopo aver fatto questo, si usino le routine descritte in questa sezione per ottenere e modificare il valore usando il value cookie. Quindi, do_magic() diviene ora qualcosa del tipo:

/*  do_magic --- fai qualcosa di veramente grande */

static awk_value_t *
do_magic(int nargs, awk_value_t *risultato)
{
    awk_value_t valore;

    if (   sym_lookup_scalar(magic_var_cookie, AWK_NUMBER, & valore)
        && qualche_condizione(valore.num_valore)) {
            valore.num_valore += 42;
            sym_update_scalar(magic_var_cookie, & valore);
    }
    …

    return make_number(0.0, risultato);
}

NOTA: Il codice appena visto omette il controllo di eventuali errori, per amor di semplicità. Il codice dell’estensione dovrebbe essere più complesso e controllare attentamente i valori restituiti dalle funzioni dell’API.


Note a piè di pagina

(111)

La differenza è misurabile e indubbiamente reale. Fidatevi.


Successivo: , Precedente: , Su: Accedere alla tabella simboli   [Contenuti][Indice]