Quali sono le strutture dati sottostanti utilizzate per Redis?


305

Sto cercando di rispondere a due domande in un elenco definitivo:

  1. Quali sono le strutture dati sottostanti utilizzate per Redis?
  2. E quali sono i principali vantaggi / svantaggi / casi d'uso per ciascun tipo?

Quindi, ho letto che le liste Redis sono effettivamente implementate con liste collegate. Ma per altri tipi, non sono in grado di estrarre alcuna informazione. Inoltre, se qualcuno dovesse inciampare su questa domanda e non avere un riepilogo di alto livello dei pro e contro della modifica o dell'accesso a diverse strutture di dati, avrebbe un elenco completo di quando utilizzare al meglio tipi specifici come riferimento.

In particolare, sto cercando di delineare tutti i tipi: stringa, elenco, set, zset e hash.

Oh, ho visto questi articoli, tra gli altri, finora:


7
Come usare un server è curiosità? Come faccio a determinare quando utilizzare una struttura di programmazione rispetto a un'altra? Questo è direttamente applicabile alla programmazione, poiché utilizzerei tipi diversi per usi diversi.
Homer6

2
Come usare un server non è necessariamente banale, ma è fuori tema - e non è quello che hai chiesto. Quali strutture di dati utilizzare per scopi specifici sarebbero di attualità, ma non è nemmeno quello che hai chiesto. Ciò che è accaduto per essere usato in Redis sono curiosità, in assenza di ulteriori ragionamenti sul perché hanno usato una struttura particolare in una situazione particolare - a quel punto, torniamo a ciò che ho già detto sarebbe di attualità, e ciò che Redis capita di fare è irrilevante.
Jerry Coffin

5
L'argomento afferma chiaramente: "Quali sono le strutture di dati e quando dovresti usare tipi diversi?" Com'è fuori tema? Stai dicendo che imparare a conoscere elenchi, hash e array collegati è irrilevante per la programmazione? Perché, direi che sono direttamente rilevanti, specialmente in un server progettato principalmente per le prestazioni. Inoltre, sono rilevanti perché la scelta sbagliata potrebbe significare sostanzialmente meno prestazioni da un'applicazione all'altra.
Homer6

19
La risposta di Antirez riscatta questa domanda. vicino a scapito di programmatori e utenti redis ovunque.
John Sheehan

75
@JerryCoffin con tutto il rispetto, redis è uno strumento di sviluppo software e porre domande sugli strumenti di sviluppo software è saldamente in argomento. Il fatto che "puoi ottenere la risposta dalla fonte" non è un motivo stretto ... ci vorrebbero ore per ottenere la risposta dalla fonte. E redis è molto usato, quindi questa domanda non è troppo localizzata. Stack Overflow riguarda l'apprendimento della programmazione e la domanda su quale struttura di dati viene utilizzata da uno strumento di programmazione estremamente popolare che contribuisce a tale obiettivo. In breve non riesco a trovare alcun motivo per chiudere questa domanda.
Joel Spolsky

Risposte:


612

Cercherò di rispondere alla tua domanda, ma inizierò con qualcosa che potrebbe sembrare strano all'inizio: se non sei interessato agli interni di Redis, non dovresti preoccuparti di come i tipi di dati vengono implementati internamente. Questo per una semplice ragione: per ogni operazione Redis troverai la complessità temporale nella documentazione e, se hai l'insieme di operazioni e la complessità temporale, l'unica altra cosa di cui hai bisogno è qualche indizio sull'uso della memoria (e perché facciamo molte ottimizzazioni che possono variare a seconda dei dati, il modo migliore per ottenere queste ultime cifre sta facendo alcuni banali test nel mondo reale).

Ma da quando hai chiesto, ecco l'implementazione sottostante di ogni tipo di dati Redis.

  • Le stringhe vengono implementate utilizzando una libreria di stringhe dinamiche C in modo da non pagare (asintoticamente parlando) le allocazioni nelle operazioni di accodamento. In questo modo abbiamo O (N), ad esempio, invece di avere un comportamento quadratico.
  • Gli elenchi sono implementati con elenchi collegati.
  • Set e hash sono implementati con tabelle hash.
  • I set ordinati sono implementati con skip list (un tipo peculiare di alberi bilanciati).

Ma quando gli elenchi, i set e i set ordinati sono piccoli in numero di elementi e dimensioni dei valori più grandi, viene utilizzata una codifica diversa, molto più compatta. Questa codifica differisce per diversi tipi, ma ha la caratteristica di essere un blocco compatto di dati che spesso forza una scansione O (N) per ogni operazione. Poiché utilizziamo questo formato solo per piccoli oggetti, questo non è un problema; scansionare un piccolo blob O (N) è cache ignaro, quindi praticamente è molto veloce e quando ci sono troppi elementi la codifica viene automaticamente passata alla codifica nativa (elenco collegato, hash e così via).

Ma la tua domanda non riguardava solo gli interni, il tuo punto era: che tipo usare per realizzare cosa? .

stringhe

Questo è il tipo base di tutti i tipi. È uno dei quattro tipi, ma è anche il tipo base dei tipi complessi, poiché un Elenco è un elenco di stringhe, un Set è un insieme di stringhe e così via.

Una stringa Redis è una buona idea in tutti gli scenari ovvi in ​​cui si desidera archiviare una pagina HTML, ma anche quando si desidera evitare di convertire i dati già codificati. Ad esempio, se si dispone di JSON o MessagePack, è possibile archiviare oggetti come stringhe. In Redis 2.6 puoi persino manipolare questo tipo di lato server degli oggetti usando gli script Lua.

Un altro uso interessante delle stringhe è la bitmap, e in generale matrici di accesso casuale di byte, dal momento che Redis esporta i comandi per accedere a intervalli casuali di byte, o anche singoli bit. Ad esempio, controlla questo buon post sul blog: le metriche di Fast Easy in tempo reale con Redis .

elenchi

Gli elenchi sono utili quando è probabile che tocchi solo gli estremi dell'elenco: vicino alla coda o vicino alla testa. Le liste non sono molto buone per impaginare le cose, perché l'accesso casuale è lento, O (N). Quindi un buon uso degli elenchi sono semplici code e pile o l'elaborazione di elementi in un ciclo usando RPOPLPUSH con la stessa origine e destinazione per "ruotare" un anello di elementi.

Gli elenchi sono utili anche quando vogliamo solo creare una raccolta limitata di N articoli in cui di solito accediamo solo agli elementi in alto o in basso o quando N è piccolo.

Imposta

I set sono una raccolta di dati non ordinata, quindi sono validi ogni volta che si dispone di una raccolta di elementi ed è molto importante controllare l'esistenza o le dimensioni della raccolta in modo molto rapido. Un'altra cosa interessante dei set è il supporto per sbirciare o far scoppiare elementi casuali (comandi SRANDMEMBER e SPOP).

Gli insiemi sono anche buoni per rappresentare le relazioni, ad esempio "Cosa sono gli amici dell'utente X?" e così via. Ma altre buone strutture di dati per questo tipo di cose sono insiemi ordinati come vedremo.

Imposta il supporto di operazioni complesse come intersezioni, unioni e così via, quindi questa è una buona struttura di dati per l'utilizzo di Redis in modo "computazionale", quando si dispone di dati e si desidera eseguire trasformazioni su tali dati per ottenere un output.

I piccoli set sono codificati in modo molto efficiente.

hash

Gli hash sono la struttura dati perfetta per rappresentare oggetti, composta da campi e valori. I campi di hash possono anche essere incrementati atomicamente usando HINCRBY. Quando hai oggetti come utenti, post di blog o qualche altro tipo di elemento , è probabile che gli hash siano la strada da percorrere se non vuoi usare la tua codifica come JSON o simili.

Tuttavia, tieni presente che i piccoli hash sono codificati in modo molto efficiente da Redis e puoi chiedere a Redis di ottenere, SET o incrementare atomicamente i singoli campi in modo molto veloce.

Gli hash possono anche essere usati per rappresentare strutture di dati collegate, usando riferimenti. Ad esempio, controlla l'implementazione dei commenti su lamernews.com.

Set ordinati

I set ordinati sono le uniche altre strutture dati, oltre agli elenchi, per mantenere gli elementi ordinati . Puoi fare una serie di cose interessanti con set ordinati. Ad esempio, puoi avere tutti i tipi di elenchi Top Something nella tua applicazione web. I migliori utenti per punteggio, i migliori post per visualizzazioni di pagina, i migliori in ogni caso, ma un'unica istanza Redis supporterà tonnellate di operazioni di inserimento e get-top-element al secondo.

I set ordinati, come i set regolari, possono essere utilizzati per descrivere le relazioni, ma consentono anche di impaginare l'elenco degli articoli e di ricordare l'ordinamento. Ad esempio, se ricordo gli amici dell'utente X con un set ordinato, posso facilmente ricordarli in ordine di amicizia accettata.

I set ordinati sono validi per le code prioritarie.

I set ordinati sono come elenchi più potenti in cui l'inserimento, la rimozione o l'acquisizione di intervalli dal centro dell'elenco è sempre rapido. Ma usano più memoria e sono strutture dati O (log (N)).

Conclusione

Spero di aver fornito alcune informazioni in questo post, ma è molto meglio scaricare il codice sorgente di lamernews da http://github.com/antirez/lamernews e capire come funziona. Molte strutture di dati di Redis sono utilizzate all'interno di Lamer News e ci sono molti indizi su cosa usare per risolvere un determinato compito.

Ci scusiamo per gli errori di grammatica, è mezzanotte qui e troppo stanco per rivedere il post;)


45
Questo è l'unico autore di Redis. Gli ho mandato un'email e gli ho chiesto di rispondere. Grazie mille Salvatore. Questa è un'ottima informazione.
Homer6

58
Grazie, ma non sono l'unico grande collaboratore, Pieter Noordhuis ha fornito parti molto importanti dell'attuale implementazione :)
antirez

1
Se una stringa identica si trova in molti set diversi, verrà memorizzata solo una singola copia della stringa?
sbrian,

In che modo zscore è in O (1) usando solo un skip list?
Maxime

1
Mentre uno skiplist non è un albero bilanciato appropriato, puoi vedere uno skiplist come un albero casuale "invertito". Sono sostanzialmente equivalenti anche se l'implementazione e il layout differiscono.
Antirez,

80

Il più delle volte, non è necessario comprendere le strutture dati sottostanti utilizzate da Redis. Ma un po 'di conoscenza ti aiuta a compensare la memoria della CPU v / s. Ti aiuta anche a modellare i tuoi dati in modo efficiente.

Internamente, Redis utilizza le seguenti strutture di dati:

  1. Corda
  2. Dizionario
  3. Elenco doppiamente collegato
  4. Salta la lista
  5. Elenco zip
  6. Int Sets
  7. Mappe zip (deprecate a favore della lista zip da Redis 2.6)

Per trovare la codifica utilizzata da un determinato tasto, utilizzare il comando object encoding <key>.

1. Stringhe

In Redis, le stringhe sono chiamate stringhe dinamiche semplici o SDS . È un wrapper di dimensioni ridotte rispetto a un char *che consente di memorizzare la lunghezza della stringa e il numero di byte liberi come prefisso.

Poiché la lunghezza della stringa è memorizzata, strlen è un'operazione O (1). Inoltre, poiché la lunghezza è nota, le stringhe Redis sono binarie sicure. È perfettamente legale che una stringa contenga il carattere null .

Le stringhe sono la struttura di dati più versatile disponibile in Redis. Una stringa è tutto di quanto segue:

  1. Una stringa di caratteri che può memorizzare il testo. Vedi i comandi SET e GET .
  2. Un array di byte in grado di memorizzare dati binari.
  3. A longche può memorizzare numeri. Vedi i comandi INCR , DECR , INCRBY e DECRBY .
  4. Una matrice (di chars, ints, longso qualsiasi altro tipo di dati) che può consentire l'accesso casuale efficiente. Vedi i comandi SETRANGE e GETRANGE .
  5. Un array di bit che consente di impostare o ottenere singoli bit. Vedi i comandi SETBIT e GETBIT .
  6. Un blocco di memoria che è possibile utilizzare per creare altre strutture di dati. Viene utilizzato internamente per creare elenchi zip e inserti, che sono strutture dati compatte ed efficienti in termini di memoria per un numero ridotto di elementi. Maggiori informazioni su questo sotto.

2. Dizionario

Redis utilizza un dizionario per quanto segue:

  1. Per mappare una chiave al suo valore associato, dove valore può essere una stringa, un hash, un set, un set o un elenco ordinati.
  2. Per mappare una chiave al relativo timestamp di scadenza.
  3. Per implementare i tipi di dati Hash, Set e Sorted Set.
  4. Mappare i comandi Redis sulle funzioni che gestiscono tali comandi.
  5. Per mappare una chiave Redis su un elenco di client che sono bloccati su quella chiave. Vedi BLPOP .

I dizionari Redis sono implementati usando le tabelle hash . Invece di spiegare l'implementazione, spiegherò solo le cose specifiche di Redis:

  1. I dizionari usano una struttura chiamata dictTypeper estendere il comportamento di una tabella hash. Questa struttura ha puntatori di funzione e quindi le seguenti operazioni sono estendibili: a) funzione hash, b) confronto di chiavi, c) distruttore di chiavi e d) distruttore di valori.
  2. I dizionari usano murmurhash2 . (Precedentemente usavano la funzione hash djb2 , con seed = 5381, ma poi la funzione hash era passata a murmur2 . Vedi questa domanda per una spiegazione dell'algoritmo hash djb2 .)
  3. Redis utilizza l'hashing incrementale, noto anche come ridimensionamento incrementale . Il dizionario ha due tabelle hash. Ogni volta che si tocca il dizionario , viene migrato un bucket dalla prima (piccola) tabella hash alla seconda. In questo modo, Redis impedisce un'operazione di ridimensionamento costoso.

La Setstruttura dei dati utilizza un dizionario per garantire che non vi siano duplicati. Il Sorted Setutilizza un dizionario per mappare un elemento al suo punteggio, ed è per questo Zscore è un (1) il funzionamento O.

3. Elenchi doppiamente collegati

Il listtipo di dati viene implementato utilizzando le liste doppiamente collegate . L'implementazione di Redis è direttamente dal manuale dell'algoritmo. L'unica modifica è che Redis memorizza la lunghezza nella struttura dei dati dell'elenco. Ciò garantisce che LLEN abbia una complessità O (1).

4. Salta elenchi

Redis utilizza gli Skip List come struttura dati sottostante per i set ordinati. Wikipedia ha una buona introduzione. La Skip List di William Pugh : un'alternativa probabilistica agli alberi equilibrati ha maggiori dettagli.

I set ordinati utilizzano sia un elenco di salto che un dizionario. Il dizionario memorizza il punteggio di ciascun elemento.

L'implementazione di Skip List di Redis è diversa dall'implementazione standard nei seguenti modi:

  1. Redis consente punteggi duplicati. Se due nodi hanno lo stesso punteggio, vengono ordinati in base all'ordine lessicografico .
  2. Ogni nodo ha un puntatore indietro a livello 0. Ciò consente di attraversare elementi in ordine inverso rispetto al punteggio.

5. Elenco zip

Un elenco zip è come un elenco doppiamente collegato, tranne per il fatto che non utilizza i puntatori e memorizza i dati in linea.

Ogni nodo in un elenco doppiamente collegato ha 3 puntatori: un puntatore in avanti, un puntatore all'indietro e un puntatore per fare riferimento ai dati memorizzati in quel nodo. I puntatori richiedono memoria (8 byte su un sistema a 64 bit), quindi per elenchi di piccole dimensioni un elenco doppiamente collegato è molto inefficiente.

Una lista zip memorizza gli elementi in sequenza in una stringa Redis. Ogni elemento ha una piccola intestazione che memorizza la lunghezza e il tipo di dati dell'elemento, l'offset all'elemento successivo e l'offset all'elemento precedente. Questi offset sostituiscono i puntatori avanti e indietro. Poiché i dati sono archiviati in linea, non abbiamo bisogno di un puntatore di dati.

L'elenco Zip viene utilizzato per memorizzare piccoli elenchi, set ordinati e hash. I set ordinati vengono appiattiti in un elenco come [element1, score1, element2, score2, element3, score3]e memorizzati nell'elenco Zip. Gli hash vengono appiattiti in un elenco come [key1, value1, key2, value2]ecc.

Con le liste zip hai il potere di fare un compromesso tra CPU e memoria. Gli elenchi zip sono efficienti in termini di memoria, ma utilizzano più CPU di un elenco collegato (o tabella hash / elenco di salto). Trovare un elemento nella lista zip è O (n). L'inserimento di un nuovo elemento richiede la riallocazione della memoria. Per questo motivo, Redis utilizza questa codifica solo per piccoli elenchi, hash e set ordinati. È possibile modificare questo comportamento modificando i valori di <datatype>-max-ziplist-entriese <datatype>-max-ziplist-value>in redis.conf. Vedere Redis Memory Optimization, sezione "Codifica speciale di piccoli tipi di dati aggregati" per ulteriori informazioni.

I commenti su ziplist.c sono eccellenti e puoi comprendere completamente questa struttura di dati senza dover leggere il codice.

6. Int Sets

Gli insiemi int sono un nome di fantasia per "array di numeri interi ordinati".

In Redis, i set sono generalmente implementati usando le tabelle hash. Per piccoli insiemi, una tabella hash è inefficiente dal punto di vista della memoria. Quando il set è composto solo da numeri interi, un array è spesso più efficiente.

Un set Int è un array ordinato di numeri interi. Per trovare un elemento viene utilizzato un algoritmo di ricerca binaria . Ciò ha una complessità di O (log N). L'aggiunta di nuovi numeri interi a questo array può richiedere una riallocazione della memoria, che può diventare costosa per array di interi di grandi dimensioni.

Come ulteriore ottimizzazione della memoria, Int Set è disponibile in 3 varianti con diverse dimensioni di interi: 16 bit, 32 bit e 64 bit. Redis è abbastanza intelligente da usare la variante giusta a seconda della dimensione degli elementi. Quando viene aggiunto un nuovo elemento e supera la dimensione corrente, Redis lo migra automaticamente alla dimensione successiva. Se viene aggiunta una stringa, Redis converte automaticamente Int Set in un normale set basato su Hash Table.

I set int sono un compromesso tra CPU e memoria. I set Int sono estremamente efficienti in termini di memoria e per i set più piccoli sono più veloci di una tabella hash. Ma dopo un certo numero di elementi, il tempo di recupero di O (log N) e il costo di riallocare la memoria diventano troppo. Sulla base di esperimenti, la soglia ottimale per passare a una tabella hash normale è stata trovata a 512. Tuttavia, è possibile aumentare questa soglia (diminuendola non ha senso) in base alle esigenze dell'applicazione. Vedi set-max-intset-entriesin redis.conf.

7. Mappe zip

Le mappe zip sono dizionari appiattiti e memorizzati in un elenco. Sono molto simili alle liste zip.

Le mappe zip sono state deprecate da Redis 2.6 e piccoli hash sono memorizzati negli elenchi zip. Per ulteriori informazioni su questa codifica, consultare i commenti in zipmap.c .


2

Redis memorizza le chiavi che puntano ai valori. Le chiavi possono avere qualsiasi valore binario fino a dimensioni ragionevoli (si consiglia di utilizzare stringhe ASCII brevi per motivi di leggibilità e debug). I valori sono uno dei cinque tipi di dati Redis nativi.

1.strings - una sequenza di byte binari sicuri fino a 512 MB

2.hashes - una raccolta di coppie chiave-valore

3.lists - una raccolta di stringhe in ordine di inserimento

4.set - una raccolta di stringhe uniche senza ordinamento

5.sorted sets: una raccolta di stringhe uniche ordinate per punteggio definito dall'utente

stringhe

Una stringa Redis è una sequenza di byte.

Le stringhe in Redis sono binarie sicure (nel senso che hanno una lunghezza nota non determinata da alcun carattere di terminazione speciale), quindi puoi archiviare fino a 512 megabyte in una stringa.

Le stringhe sono il concetto di "archivio valori chiave". Hai una chiave che punta a un valore, in cui sia la chiave che il valore sono stringhe di testo o binarie.

Per tutte le possibili operazioni sulle stringhe, consultare il http://redis.io/commands/#string

hash

Un hash Redis è una raccolta di coppie chiave-valore.

Un hash Redis contiene molte coppie di valori chiave, in cui ogni chiave e valore è una stringa. Gli hash Redis non supportano direttamente valori complessi (nel senso che non è possibile che un campo hash abbia un valore di un elenco o set o un altro hash), ma è possibile utilizzare i campi hash per puntare ad altri valori complessi di livello superiore. L'unica operazione speciale che puoi eseguire sui valori del campo hash è l'incremento / decremento atomico dei contenuti numerici.

Puoi pensare a un hash Redis in due modi: come una rappresentazione diretta dell'oggetto e come un modo per memorizzare molti piccoli valori in modo compatto.

Le rappresentazioni dirette di oggetti sono semplici da capire. Gli oggetti hanno un nome (la chiave dell'hash) e una raccolta di chiavi interne con valori. Vedi l'esempio sotto per, beh, un esempio.

Memorizzare molti piccoli valori usando un hash è un'ingegnosa tecnica di archiviazione dei dati di Redis. Quando un hash ha un piccolo numero di campi (~ 100), Redis ottimizza l'archiviazione e l'efficacia dell'accesso dell'intero hash. La piccola ottimizzazione dell'archiviazione hash di Redis genera un comportamento interessante: è più efficiente avere 100 hash ciascuno con 100 chiavi e valori interni anziché avere 10.000 chiavi di livello superiore che puntano a valori di stringa. L'uso degli hash Redis per ottimizzare l'archiviazione dei dati in questo modo richiede un sovraccarico di programmazione aggiuntivo per il tracciamento in cui finiscono i dati, ma se l'archiviazione dei dati è basata principalmente su stringhe, è possibile risparmiare un sacco di overhead di memoria usando questo strano trucco.

Per tutte le possibili operazioni sugli hash, consultare i documenti hash

elenchi

Le liste Redis si comportano come liste collegate.

È possibile inserire, eliminare da e attraversare elenchi dalla testa o dalla coda di un elenco.

Utilizzare gli elenchi quando è necessario mantenere i valori nell'ordine in cui sono stati inseriti. (Redis ti dà la possibilità di inserire in qualsiasi posizione di elenco arbitraria se necessario, ma le prestazioni di inserimento peggioreranno se inserisci lontano dalla posizione iniziale.)

Gli elenchi Redis sono spesso utilizzati come code produttore / consumatore. Inserisci gli elementi in un elenco, quindi pop gli elementi dall'elenco. Cosa succede se i tuoi consumatori provano ad apparire da un elenco senza elementi? Puoi chiedere a Redis di attendere che appaia un elemento e di restituirlo immediatamente quando viene aggiunto. Questo trasforma Redis in un sistema di code / eventi / lavori / compiti / notifiche in tempo reale.

Puoi rimuovere atomicamente gli elementi da una delle estremità di un elenco, consentendo a qualsiasi elenco di essere trattato come uno stack o una coda.

Puoi anche mantenere elenchi a lunghezza fissa (raccolte limitate) tagliando l'elenco a una dimensione specifica dopo ogni inserimento.

Per tutte le possibili operazioni sugli elenchi, consultare i documenti degli elenchi

Imposta

I set di Redis sono, beh, set.

Un set Redis contiene stringhe Redis uniche non ordinate in cui ogni stringa esiste una sola volta per set. Se aggiungi lo stesso elemento dieci volte a un set, verrà visualizzato solo una volta. I set sono fantastici per garantire pigramente che qualcosa esista almeno una volta senza preoccuparsi degli elementi duplicati che accumulano e sprecano spazio. Puoi aggiungere la stessa stringa tutte le volte che vuoi senza bisogno di verificare se esiste già.

I set sono veloci per il controllo dell'iscrizione, l'inserimento e l'eliminazione dei membri nel set.

I set hanno operazioni di set efficienti, come ci si aspetterebbe. Puoi prendere l'unione, l'intersezione e la differenza di più insiemi contemporaneamente. I risultati possono essere restituiti al chiamante oppure i risultati possono essere memorizzati in un nuovo set per un uso successivo.

I set hanno accesso a tempo costante per i controlli di appartenenza (a differenza degli elenchi) e Redis ha anche una comoda rimozione e restituzione dei membri casuali ("pop un elemento casuale dal set") o dei membri casuali che ritornano senza sostituzione ("dammi 30 utenti unici casuali) ") o con sostituzione (" dammi 7 carte, ma dopo ogni selezione, rimetti la carta in modo che possa essere nuovamente campionata ").

Per tutte le possibili operazioni sui set, consultare la documentazione dei set .

Set ordinati

Gli insiemi ordinati Redis sono insiemi con un ordine definito dall'utente.

Per semplicità, puoi pensare a un set ordinato come un albero binario con elementi unici. (I set ordinati Redis sono in realtà salta elenchi .) L'ordinamento degli elementi è definito dal punteggio di ciascun elemento.

Gli insiemi ordinati sono ancora insiemi. Gli elementi possono apparire solo una volta in un set. Un elemento, a fini di unicità, è definito dal suo contenuto di stringa. Inserendo l'elemento "mela" con il punteggio di ordinamento 3, quindi inserendo l'elemento "mela" con il punteggio di ordinamento 500 si ottiene un elemento "mela" con il punteggio di ordinamento 500 nel set ordinato. Gli insiemi sono univoci solo in base a Dati, non in base a coppie (Punteggio, Dati).

Assicurati che il tuo modello di dati si basi sul contenuto della stringa e non sul punteggio dell'elemento per unicità. I punteggi possono essere ripetuti (o addirittura zero), ma, un'ultima volta, gli elementi del set possono esistere solo una volta per set ordinato. Ad esempio, se si tenta di memorizzare la cronologia di ogni accesso utente come un set ordinato impostando il punteggio nell'epoca dell'accesso e il valore dell'ID utente, si finirà per memorizzare solo l'ultima epoca dell'accesso per tutti i propri utenti. Il set aumenterebbe fino alla dimensione della base utente e non alla dimensione desiderata per l'accesso alla base utente *.

Gli elementi vengono aggiunti al tuo set con punteggi. Puoi aggiornare il punteggio di qualsiasi elemento in qualsiasi momento, basta aggiungere nuovamente l'elemento con un nuovo punteggio. I punteggi sono rappresentati da doppie in virgola mobile, quindi è possibile specificare la granularità di timestamp di alta precisione, se necessario. Più elementi possono avere lo stesso punteggio.

Puoi recuperare elementi in diversi modi. Poiché tutto è ordinato, puoi chiedere elementi a partire dal punteggio più basso. Puoi chiedere elementi a partire dal punteggio più alto ("al contrario"). Puoi richiedere gli elementi in base al loro punteggio di ordinamento in ordine naturale o inverso.

Per tutte le possibili operazioni sui set ordinati, consultare la documentazione relativa ai set ordinati.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.