2012-01-10 27 views

Respuesta

10

Puede almacenar prácticamente cualquier cosa en LevelDB. Proporciona segmentos opacos de datos en LevelDB a través de la estructura Slice. He aquí un ejemplo:

int intKey = 256; 
int intValue = 256*256; 

Slice key((char*)&intKey, sizeof(int)); 
Slice value((char*)&intValue, sizeof(int)); 

db->Put(leveldb::WriteOptions(), key, value); 

Y eso es prácticamente todo!

Sin embargo, una cosa a destacar es que si bien es en general bien para almacenar números enteros en LevelDB (como las claves y valores), que serán orden a través de la BytewiseComparator así su clave tiene que apoyar byte a byte de comparación. Esto también significa que si confías en el orden específico de las claves, entonces debes ser consciente de la endianidad del sistema.

También puede escribir su propio comparador a través de la interfaz Comparator que le permitirá reemplazar el valor predeterminado BytewiseComparator.

+0

Pero el Get no me da rebanada, ¿verdad? Si los datos no están '0' rellenos, ¿cómo funcionará? ¿O me falta algo aquí? – vinothkr

+0

Obtener devuelve una std :: cadena que puede contener una matriz de bytes arbitraria. También puede usar un iterador y buscar con él, para poder obtener un Slice apuntando al valor sin ninguna copia requerida. Este es el enfoque recomendado para valores muy grandes. –

1

En muchos casos, una mejor opción es un esquema de codificación más elaborado para las claves de enteros. Empacar un int en su representación de dos complementos en un char * (como se sugiere en otra respuesta a esta pregunta) es una opción; La codificación varint es otra (ahorra espacio para enteros pequeños, puede almacenar números arbitrarios sin un límite superior).

+0

¿No es varint una optimización del método de dos complementos? – amirouche

+1

no. los varints (que tienen múltiples variantes) usan un tamaño variable, mientras que los números de dos complementos usan un tamaño fijo. esto significa que los varints son teóricamente ilimitados (pero no en implementaciones prácticas), mientras que los números de dos complementos tienen un rango de -2^n a 2^n-1. Además, los varints necesitan una codificación en zigzag para los números negativos, mientras que los 2 complementos se reservan un bit de signo para eso. –

0

Para ampliar la respuesta de Link, en parte porque acabo de jugar con esto exactamente como parte del libro que estoy escribiendo, puede ver los resultados de BytewiseComparator de los que habla a continuación.

Otro enfoque es voltear sus enteros binarios al formato de Big Endian para que clasifiquen bien con el comparador predeterminado. Esto hace que sea más fácil componer claves. long flippedI = htonl(i);

Tenga en cuenta que LevelDB es muy rápido. He hecho pruebas en un iPhone4 con 50,000 registros con clave de texto con claves secundarias, por lo que aproximadamente 100,000 pares de clave/valor y grita.

Es muy fácil escribir un comparador personalizado que su base de datos utiliza para siempre y aún utiliza ByteWiseComparator para claves que no sean sus números. El mayor problema es decidir qué claves están cubiertas por sus reglas personalizadas o no.

Una forma trivial sería decir que todas las claves no enteros tienen más de 4 caracteres, por lo que supone que una clave de 4 bytes es un número entero. Eso significa que solo necesita asegurarse de agregar espacios finales u otra cosa para impulsar eso. Es muy arbitrario y depende de usted, pero recuerde que las únicas dos piezas de información que tiene son el contenido clave y su longitud. No hay otros metadatos para una clave dada.

Parte de los resultados de una muestra para el comparador estándar con teclas int a partir de 1 y subiendo por 1 a 1000, utilizando una base de datos con BytewiseComparator estándar

Listing the keys in decimal and hex 
256 (100) 
512 (200) 
768 (300) 
    1 ( 1) 
257 (101) 
513 (201) 
769 (301) 
    2 ( 2) 
258 (102) 
514 (202) 
770 (302) 
    3 ( 3) 
259 (103) 
515 (203) 
771 (303) 
... 
254 ( fe) 
510 (1fe) 
766 (2fe) 
255 ( ff) 
511 (1ff) 
767 (2ff) 
+0

Te refieres a voltearse en el orden big-endian, no little-endian. Usaste "htonl" en tu ejemplo que significa "host a la red" y el orden de bytes de la red es big-endian. LevelDB puede ser rápido en comparación con otras bases de datos antiguas, pero es bastante lento en comparación con LMDB. – hyc

+0

Gracias por la corrección en endianness. –

0

LMDB tiene soporte explícito para las claves de enteros (y valores, si está utilizando duplicados ordenados). http://symas.com/mdb

Cuando un DB está configurado para claves enteras, las funciones de comparación de teclas también son mucho más rápidas, ya que pueden comparar palabra por palabra en lugar de solo byte a la vez como la comparación por cadena predeterminada hace.

Descargo de responsabilidad: soy el autor de LMDB. Por supuesto, eso no hace que los hechos sean diferentes.

+1

La pregunta era sobre LevelDB. Deje de enviar otras preguntas para tratar de promocionar LMDB. –

+0

La pregunta dice "He buscado", lo que significa que todavía está buscando opciones. Y LevelDB es una opción probadamente inferior, y LMDB es una opción probadamente superior. – hyc

+0

@hyc que más bien depende de sus requisitos. Acabo de revisar LMDB y lo encontré completamente inadecuado, sin embargo, LevelDB parece hacer justo lo que necesito. – Alnitak

Cuestiones relacionadas