Le stringhe si prestano ad una moltitudine di utilizzi, che variano dalla manipolazione di informazioni testuali, alla gestione di numeri fino ai dati binari. Nei prossimi paragrafi vediamo le funzioni disponibili per manipolazione le stringhe, che costituiranno il nostro armamentario di base per lavorare in Redis.
Manipolazione di stringhe
Redis offre molte funzioni per la manipolazione di stringhe, implementando operazioni come concatenazione di testo, lettura della dimensione e gestione di sottostringhe. Nell'esempio seguente, salviamo una stringa con chiave "frase", e ne leggiamo la lunghezza:
> SET frase "meglio un uovo oggi"
OK
> STRLEN frase
(integer) 19
Concateniamo un'altra porzione di stringa con APPEND e ne riceviamo subito come risultato la dimensione senza invocare STRLEN:
> APPEND frase " che una gallina domani"
(integer) 42
Con le funzioni GETRANGE e SETRANGE, rispettivamente, leggiamo una sottostringa (gli indici vengono conteggiati a partire da 0) e ne
impostiamo il valore:
> GETRANGE frase 0 13
"meglio un uovo"
> SETRANGE frase 24 "uno struzzo "
(integer) 42
La versione finale della stringa equivale a "meglio un uovo oggi che uno struzzo domani".
Incrementare e decrementare numeri
Considerando che le stringhe possono contenere anche numeri, Redis offre delle funzioni per poterne velocemente incrementare e
decrementare il valore di un'unità o più. L'attività può essere molto utile se si pensa che spesso capiterà di dover eseguire dei conteggi in maniera efficiente, relativi ad operazioni svolte dall'utente o interne all'applicazione. Nel seguente esempio, creiamo una nuova chiave, "contatti", inizializzata a 1, e svolgiamo delle attività di incremento singolo o multiplo (INCR e INCRBY). Analogamente, vedremo anche come decrementarne il valore con DECR e DECRBY:
> SET contatti 1
OK
> INCR contatti
(integer) 2
> INCR contatti
(integer) 3
> INCRBY contatti 4
(integer) 7
> DECRBY contatti 2
(integer) 5
> DECR contatti
(integer) 4
Esiste anche una versione di incremento peer i numeri decimali (con virgola), INCRBYFLOAT.
Manipolazione binaria
Le stringhe possono essere utilizzate come un grande aggregato di bit (bitmap). Con le funzioni che stiamo per vedere, possiamo manipolare un insieme di bit legati ad una chiave, impostando anche singoli di essi al valore 1 o 0. La funzione SETBIT imposta il valore di un bit in una determinata posizione, restituendo in output il precedente valore del bit stesso. Ad esempio, la seguente operazione imposta a 1 il quarto bit (numero 3 a partire
da 0) del valore collegato alla chiave "parola". L'operazione riesce e viene restituito il vecchio valore del bit ossia 0:
> SETBIT parola 3 1
(integer) 0
Per verificare il valore inserito, si può procedere con GETBIT, al fine di avere conferma del singolo bit, oppure con GET
:
> GETBIT parola 3
(integer) 1
> GET parola
"\x10"
Si noti che la funzione GET
ha restituito la forma esadecimale dello spazio occupato corrispondente al numero 10, ossia 00010000 in binario dove si
vede il bit numero 3 da sinistra impostato a 1. Possiamo eseguire altre prove dello stesso tenore ed infine ottenere il numero di bit impostati a 1
con BITCOUNT:
> SETBIT parola 5 1
(integer) 0
> GET parola
"\x14"
> BITCOUNT parola
(integer) 2
Con la funzione BITPOS possiamo chiedere in che posizione si trovi il primo bit impostato a 0 o a 1. Il primo esempio che segue
dimostra che il primo bit a 1 si trova in posizione 2 e il primo bit a 0 in posizione 0:
> BITPOS parola 1
(integer) 3
> BITPOS parola 0
(integer) 0
Un'altra funzione molto utile è BITOP, che permette di specificare un'operazione bit a bit da svolgere. Come altri argomenti, richiede la variabile destinazione e successivamente tutte le variabili operando. Nel seguente esempio, mostriamo come "(" e "U" sottoposte a operazione di OR diano come risultato "}".
> SET car1 (
OK
> SET car2 U
OK
> BITOP OR car3 car1 car2
(integer) 1
> GET car3
"}"
In realtà l'operazione viene svolta tra i loro codici ASCII espressi in binario come schematizziamo nella figura seguente:
Possiamo svolgere operazioni analoghe con gli operatori AND
, NOT
e XOR
. La manipolazione dei bit si presta ad usi molto utili benchè non banali: si pensi che i valori 1 e 0 di un bit possono essere visti come un true o false booleani, in modo da usare uno o più byte come contenitori per sequenze di opzioni che tollerino
solo due valori.
Implementazione di HyperLogLog
È possibile implementare in Redis anche HyperLogLog, un algoritmo probabilistico che permette di verificare velocemente la cardinalità di insiemi anche
molto grandi usando pochissime risorse. Con la funzione PFADD possiamo aggiungere elementi ad un determinato insieme. Con il seguente esempio creiamo la chiave
"insieme" e inseriamo nel suo valore sei numeri completamente diversi. Il risultato è 1, il che significa che la cardinalità dell'insieme è cambiata:
> PFADD insieme 1 2 3 4 5 6
(integer) 1
Con PFCOUNT, possiamo sapere quanti sono gli elementi al suo interno:
> PFCOUNT insieme
(integer) 6
Aggiungendo ulteriori elementi già presenti nell'insieme, ci accorgiamo che la cardinalità non cambia: infatti, PFADD
restituisce 0 e PFCOUNT
mostra lo stesso risultato di prima:
> PFADD insieme 3 6
(integer) 0
> PFCOUNT insieme
(integer) 6
Possiamo anche aggregare due insiemi con la funzione PFMERGE. Nel seguente esempio aggreghiamo due insiemi con un totale di 11 elementi di cui però due duplicati. Pertanto il risultato finale sarà un insieme di cardinalità 9.
PFADD insieme2 3 6 9 11 12
(integer) 1
> PFMERGE totale insieme insieme2
OK
> PFCOUNT totale
(integer) 9
Abbiamo parlato di HyperLogLog in questa lezione perchè tali dati non vengono memorizzati come una struttura dati, ma sotto forma di stringa (in un formato particolare) e ciò è verificabile con GET
:
> GET insieme
"HYLL\x01\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00A\xee\x84H#\x80SQ\x80Mt\x80Q,\x8c@\xcf\x84C\""