He buscado almacenes de valores clave que admitan claves enteras y valores enteros. LevelDB parece ser una buena opción, aunque no puedo encontrar ninguna información sobre si se admiten valores/claves enteros¿Se pueden almacenar claves/valores enteros en LevelDB?
Respuesta
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
.
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).
¿No es varint una optimización del método de dos complementos? – amirouche
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. –
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)
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
Gracias por la corrección en endianness. –
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.
La pregunta era sobre LevelDB. Deje de enviar otras preguntas para tratar de promocionar LMDB. –
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
@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
- 1. ¿Qué rango de valores pueden almacenar tipos enteros en C++
- 2. ¿Cuantos datos se pueden almacenar en MySQL?
- 3. ¿Se pueden ordenar n enteros en O (n) complejidad amortizada?
- 4. Una buena manera de almacenar enteros únicos
- 5. ¿LevelDB es compatible con Java?
- 6. Cómo consultar enteros, flotantes en lucene y cómo almacenar (NumericComparator)?
- 7. ¿Pueden las instantáneas de LevelDB sobrevivir al cierre de la base de datos?
- 8. ¿Cómo puedo almacenar una matriz de enteros en SharedPreferences?
- 9. ¿Debo almacenar objetos enteros o punteros a objetos en contenedores?
- 10. Los datos de límite (tamaño) se pueden almacenar en una matriz de javascript.
- 11. TypeError: sólo matrices de enteros con un elemento se pueden convertir a un índice
- 12. ¿Se pueden adivinar los id de MongoDB?
- 13. Lugar ideal para almacenar datos binarios que se pueden representar llamando a una url
- 14. ¿Se pueden usar TestContext.Properties?
- 15. ¿Cómo se almacenan los enteros de 64 bits sin signo en SQL Server?
- 16. Almacenamiento de enteros muy grandes en MySQL
- 17. ¿Estructura en disco para almacenar un conjunto grande de enteros de 128 bits?
- 18. Ensamblador en línea: ¿Qué registros de arañazos se pueden usar?
- 19. ¿Cuál es la forma más eficiente de almacenar una matriz de enteros en una columna MySQL?
- 20. ¿Se pueden usar constantes estáticas en PHP?
- 21. Archivos SVG en Raphael, ¿se pueden usar?
- 22. ¿Se pueden definir tablas "literales" en SQL?
- 23. ¿Las cadenas se pueden mutar en Ruby?
- 24. No se pueden registrar en catalina.out
- 25. ¿Se pueden duplicar las llaves en NSDictionary?
- 26. ¿Se pueden restablecer los iteradores en Python?
- 27. No se pueden agregar cadenas en C++
- 28. se pueden agrupar elementos en Interface Builder
- 29. ¿Se pueden usar formularios genéricos en C#?
- 30. No se pueden mostrar imágenes en JSP
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
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. –