Giter VIP home page Giter VIP logo

radareorg / sdb Goto Github PK

View Code? Open in Web Editor NEW
212.0 17.0 61.0 2.25 MB

Simple and fast string based key-value database with support for arrays and json

Home Page: https://www.radare.org/

License: MIT License

Makefile 6.08% Java 0.14% Lua 0.20% NewLisp 0.69% JavaScript 2.09% Python 2.73% C 56.50% Vala 3.01% C# 0.14% D 0.22% Go 0.44% C++ 21.71% HTML 0.90% Shell 3.66% Roff 0.26% Meson 0.74% Perl 0.14% V 0.34%
key-value database hashtable c data-structures hacktoberfest

sdb's Introduction

SDB (string database)

sdb is a simple string key/value database based on djb's cdb disk storage and supports JSON and arrays introspection.

mcsdbd is a memcache server with disk storage based on sdb. It is distributed as a standalone binary and a library.

There's also the sdbtypes: a vala library that implements several data structures on top of an sdb or a memcache instance.

GHA COV

Author

pancake [email protected]

Contains

  • namespaces (multiple sdb paths)
  • atomic database sync (never corrupted)
  • bindings for vala, luvit, newlisp and nodejs
  • command-line frontend for sdb databases
  • memcache client and server with sdb backend
  • arrays support (syntax sugar)
  • json parser/getter (js0n.c)

Rips

  • disk storage based on cdb code
  • linked lists from r2 api

Compilation

For native builds just type make. Everything will be compiled twice to get the .dylib and .a and sdb in PIC and nonPIC modes.

To compile with Emscripten for Javascript:

make CC=emcc EXT_EXE=.js

To crosscompile with meson:

$ cat > cross-file.txt <<EOF
[properties]
exe_wrapper = 'wine'
and then run meson build --cross-file cross-file.txt ; ninja -C build. It should work and it should create another binary called sdb_native.
EOF
$ meson build --cross-file cross-file.txt
$ ninja -C build

Changes

I have modified cdb code a little to create smaller databases and be memory leak free in order to use it from a library.

The sdb's cdb database format is 10% smaller than the original one. This is because keylen and valuelen are encoded in 4 bytes: 1 for the key length and 3 for the value length.

In a test case, a 4.3MB cdb database takes only 3.9MB after this file format change.

Usage example

Let's create a database!

$ sdb d hello=world
$ sdb d hello
world

Using arrays (>=0.6):

$ sdb - '[]list=1,2' '[0]list' '[0]list=foo' '[]list' '[+1]list=bar'
1
foo
2

Let's play with json:

$ sdb d g='{"foo":1,"bar":{"cow":3}}'
$ sdb d g:bar.cow
3
$ sdb - user='{"id":123}' user:id=99 user:id
99

Using the command-line without any disk database:

$ sdb - foo=bar foo a=3 +a -a
bar
4
3

$ sdb -
foo=bar
foo
bar
a=3
+a
4
-a
3

Remove the database

$ rm -f d

sdb's People

Contributors

0xabd avatar a1ext avatar alvarofe avatar bonniegong avatar condret avatar crowell avatar deffi420 avatar dequis avatar domenpk-samsung avatar eagleoflqj avatar eliageretto avatar j123123 avatar jvoisin avatar karel avatar lowlyw avatar maijin avatar maskray avatar meme avatar montekki avatar pelijah avatar ppentchev avatar radare avatar ratijas avatar ret2libc avatar riptl avatar tesuji avatar thestr4ng3r avatar trufae avatar xarkes avatar xvilka avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sdb's Issues

unistd.h:65:20: error: unknown type name 'off_t'

cc -c  -w  -std=c99 -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L  -Wall -g -MMD -DMINGW32=1 -g -ggdb  -o sdb.o sdb.c
In file included from c:\mingw\include\fcntl.h:37:0,
                 from sdb.c:4:
c:\mingw\include\io.h:301:1: error: unknown type name 'off64_t'
 __CRT_INLINE off64_t lseek64 (int, off64_t, int);
 ^
c:\mingw\include\io.h:301:36: error: unknown type name 'off64_t'
 __CRT_INLINE off64_t lseek64 (int, off64_t, int);
                                    ^
c:\mingw\include\io.h:302:1: error: unknown type name 'off64_t'
 __CRT_INLINE off64_t lseek64 (int fd, off64_t offset, int whence) {
 ^
c:\mingw\include\io.h:302:39: error: unknown type name 'off64_t'
 __CRT_INLINE off64_t lseek64 (int fd, off64_t offset, int whence) {
                                       ^
In file included from types.h:45:0,
                 from sdb.h:12,
                 from sdb.c:9:
c:\mingw\include\unistd.h:65:20: error: unknown type name 'off_t'
 int ftruncate(int, off_t);
                    ^
In file included from sdb.h:12:0,
                 from sdb.c:9:
types.h:79:36: error: unknown type name 'off_t'
 static inline int seek_set(int fd, off_t pos) {
                                    ^
sdb.c: In function 'sdb_new':
sdb.c:31:16: error: variable 'st' has initializer but incomplete type
         struct stat st = {0};
                ^
sdb.c:31:21: error: storage size of 'st' isn't known
         struct stat st = {0};
                     ^
Makefile:71: recipe for target 'sdb.o' failed
mingw32-make[5]: *** [sdb.o] Error 1

Add footer in sdb files (cdb)

Header may be problematic because of memory align issues. A footer like this is proposed:

05DB  : 1 nibble: version number, 3 nibbles: magic number

We also need to store the checksum, and optionally a timestamp. we can prefix them so the sdb_disk_footer() should do something like this:

928419A4 : timestamp (same as file? do we need it?)
38A0   ; checksum (crc16?)
05DB  ; magic footer

Another benefit of using footers instead of headers is that you can make it grow without breaking the hashtable.

Sdb not always synced

$ sdb d foo=bar
$ sdb d ~foo
$ sdb d foo
bar

This is because the return value of query is not correct and doesn't sets the 'must-sync' flag in main.c

sdb behaviour notes

I have some doubts about sdb.

[sdb]> -1=-1
^D
[0x0040487f]> k
1=0


[sdb]> -0=-0
^D
[0x0040487f]> k
0=0x

The point here being sdb is foo=bar store.
Also, how to clean value?

k d="" doesn't work.

Another case, what about = seperator?

[sdb]> foo=YWJjCg=Bar=Baz=wat
^D
[0x0040487f]> k
foo=YWJjCg=Bar=Baz=wat

Shouldn't this result in an error ?
Or put everything after the first
= into quotes ?

sdb_query requires const string

This shouldnt be a requirement for that function, so we would probably need a sdb_queryc() or fix sdb_query to not need writtable buffers

Implement '#' to perform sdb_hash

We can use this to avoid depending on special tools to create constant hashed strings. For example:

> #"hello"
< 0x80495

We can extend this command to work with keys too, like '%' does:

> key=hello
> #key
< 0x80495

Or set the value with it

> #key=hello
> key
< 0x80495

Also, we should extend '%' to support quoted strings.but we need to think how to specify encode or decode.

Fix 'k ***' crash

You can reproduce it this way:

r2 -c'k ***' -

Gdb says:

    frame #8: 0x0000000100cebd91 libr_db.0.9.8.git.dylib`foreach_list_cb + 177
    frame #9: 0x0000000100ceda48 libr_db.0.9.8.git.dylib`sdb_foreach + 232
    frame #10: 0x0000000100cebb79 libr_db.0.9.8.git.dylib`walk_namespace + 137
    frame #11: 0x0000000100cea088 libr_db.0.9.8.git.dylib`sdb_querys + 1864
    frame #12: 0x0000000100082d33 libr_core.0.9.8.git.dylib`cmd_kuery(data=0x0000000100005410, input=0x0000000101027ed1) + 275 at cmd.c:454
    frame #13: 0x00000001000c4a20 libr_core.0.9.8.git.dylib`r_cmd_call(cmd=0x0000000101815200, input=0x0000000101027ed0) + 352 at cmd_api.c:179

By reading the assembly this is this portion of the code:

symbol stub for: malloc
0x100cebd91:  48 b9 ff ff ff ff ff ff ff ff  movabsq $-0x1, %rcx
0x100cebd9b:  48 89 45 d0                    movq   %rax, -0x30(%rbp)
0x100cebd9f:  48 8b 7d d0                    movq   -0x30(%rbp), %rdi
0x100cebda3:  48 8b 75 e8                    movq   -0x18(%rbp), %rsi
0x100cebda7:  48 63 55 cc                    movslq -0x34(%rbp), %rdx
0x100cebdab:  e8 de 37 00 00                 callq  0x100cef58e

This is query.c:88

        line = malloc (klen + vlen + 2);

This reflects the truth that the heap has been corrupted. So, running valgrind tells us the following:

==10534== Invalid write of size 8
==10534==    at 0x11D6B8E: _platform_memmove$VARIANT$Unknown (in /usr/lib/system/libsystem_platform.dylib)
==10534==    by 0x1056D74: __memcpy_chk (in /usr/lib/system/libsystem_c.dylib)
==10534==    by 0xC8EA73: strbuf_append (in /Users/pancake/prg/radare2/libr/db/libr_db.dylib)
==10534==    by 0xC8EE11: foreach_list_cb (in /Users/pancake/prg/radare2/libr/db/libr_db.dylib)
==10534==    by 0xC90B2E: sdb_foreach (in /Users/pancake/prg/radare2/libr/db/libr_db.dylib)
==10534==    by 0xC8EB78: walk_namespace (in /Users/pancake/prg/radare2/libr/db/libr_db.dylib)
==10534==    by 0xC8ECB5: walk_namespace (in /Users/pancake/prg/radare2/libr/db/libr_db.dylib)
==10534==    by 0xC8D087: sdb_querys (in /Users/pancake/prg/radare2/libr/db/libr_db.dylib)
==10534==    by 0x25D32: cmd_kuery (in /Users/pancake/prg/radare2/libr/core/libr_core.dylib)
==10534==    by 0x67A1F: r_cmd_call (in /Users/pancake/prg/radare2/libr/core/libr_core.dylib)
==10534==    by 0x4836B: r_core_cmd_subst_i (in /Users/pancake/prg/radare2/libr/core/libr_core.dylib)
==10534==    by 0x174CF: r_core_cmd_subst (in /Users/pancake/prg/radare2/libr/core/libr_core.dylib)

There's an overflow in strbuf_append, which is quite obvious by reading the code of the function. So I have fixed it :)

Using syntax []k=1,2,3 with sdb(1) doesn't store result

Commands sdb file '[]r=3,4,5,6' '[0]r' and sdb file 'r=3,4,5,6' '[0]r' produce the same output to the console (3) but with the former the value of r isn't stored in file and file doesn't get created if it didn't exist.

This is with version b28b355 on Fedora 20 and Ubuntu 12.04. Example transcript:

dbohdan@x61s $ ls -l d2; sdb d2 '[]r=3,4,5,6' '[0]r'; sdb d2; ls -l d2
ls: cannot access d2: No such file or directory
3
ls: cannot access d2: No such file or directory
dbohdan@x61s $ ls -l d2; sdb d2 'r=3,4,5,6' '[0]r'; sdb d2; ls -l d2
ls: cannot access d2: No such file or directory
3
r=3,4,5,6
-rw-r--r--. 1 dbohdan dbohdan 2078 May 12 09:50 d2

SDB failed to create files in the Windows from the MIngw32 shell

SDB failed to create files in the Windows from the MIngw32 shell

a.kochkov@WS-ANTON ~/radare/radare2/libr/syscall/d
$ /bin/sh gen.sh < dos-x86-16 | ../../../libr/../shlr/sdb/sdb dos-x86-16.sdb =
sdb: Cannot open 'dos-x86-16.sdb.tmp' for writing.
Cannot create database
a.kochkov@WS-ANTON ~/radare/radare2/libr/syscall/d

Original error from the radare2 building process

make[3]: Entering directory `/d/Work/radare/radare2/libr/syscall'
make -C d
make[4]: Entering directory `/d/Work/radare/radare2/libr/syscall/d'
make[5]: Entering directory `/d/Work/radare/radare2/libr/syscall/d'
rm -f dos-x86-16.sdb
/bin/sh gen.sh < dos-x86-16 | ../../../libr/../shlr/sdb/sdb dos-x86-16.sdb =
make[5]: *** [dos-x86-16.sdb] Error 116
make[5]: Leaving directory `/d/Work/radare/radare2/libr/syscall/d'
make[4]: *** [all] Error 2
make[4]: Leaving directory `/d/Work/radare/radare2/libr/syscall/d'
make[3]: *** [do] Error 2

Dont use -fPIC for cygwin builds

this:

make[3]: Entering directory '/cygdrive/d/Work/radare/radare2/shlr/sdb/src'
gcc -c  -g -fPIC -o cdb.o cdb.c
cdb.c:1:0: warning: -fPIC ignored for target (all code is position independent)
 /* Public domain - author D. J. Bernstein, modified by pancake - 2014 */
 ^
gcc -c  -g -fPIC -o buffer.o buffer.c
buffer.c:1:0: warning: -fPIC ignored for target (all code is position independent)
 /* Public Domain */
 ^
gcc -c  -g -fPIC -o cdb_make.o cdb_make.c
cdb_make.c:1:0: warning: -fPIC ignored for target (all code is position independent)
 /* Public domain. */
 ^
gcc -c  -g -fPIC -o ls.o ls.c
ls.c:1:0: warning: -fPIC ignored for target (all code is position independent)
 /* sdb - LGPLv3 - Copyright 2007-2014 - pancake */
 ^

Dump/Load nested SDBs in JSON format

foo=bar
cow=123
low={"pop":123,"jiji":456}

will be dumped as:

{"foo":"bar","cow":123,"low":{"pop":123,"jiji",456}}

The nested Sdbs thing should be discussed

Printing an array with a wrong syntax

How to reproduce the issue:

[]K=1,2,3
K
1�×2×�3

With × being a piece of garbage.

The good syntax being:

[]K=1,2,3
[]K
1
2
3

Shall the wrong one return nothing ?
Imho, it should work like the working one.

Implement sdb_asort()

Sort an array trying to handle each value as numeric

sdb_array_add (DB, "key", "foo", 0);
sdb_array_add (DB, "key", "bar", 0);

Siletly doesn't create any database on w32

From the r2 compilation log:

make[2]: Entering directory `/d/Work/radare/radare2/libr'
DIR syscall
make[3]: Entering directory `/d/Work/radare/radare2/libr/syscall'
make -C d
make[4]: Entering directory `/d/Work/radare/radare2/libr/syscall/d'
make[5]: Entering directory `/d/Work/radare/radare2/libr/syscall/d'
/bin/sh gen.sh < dos-x86-16 | ../../../libr/../shlr/sdb/sdb dos-x86-16.sdb =
/bin/sh gen.sh < linux-x86-32 | ../../../libr/../shlr/sdb/sdb linux-x86-32.sdb =
/bin/sh gen.sh < linux-x86-64 | ../../../libr/../shlr/sdb/sdb linux-x86-64.sdb =
/bin/sh gen.sh < linux-arm-32 | ../../../libr/../shlr/sdb/sdb linux-arm-32.sdb =
/bin/sh gen.sh < linux-mips-32 | ../../../libr/../shlr/sdb/sdb linux-mips-32.sdb =
/bin/sh gen.sh < linux-sparc-32 | ../../../libr/../shlr/sdb/sdb linux-sparc-32.sdb =
/bin/sh gen.sh < darwin-x86-32 | ../../../libr/../shlr/sdb/sdb darwin-x86-32.sdb =
/bin/sh gen.sh < darwin-x86-64 | ../../../libr/../shlr/sdb/sdb darwin-x86-64.sdb =
/bin/sh gen.sh < netbsd-x86-32 | ../../../libr/../shlr/sdb/sdb netbsd-x86-32.sdb =
/bin/sh gen.sh < freebsd-x86-32 | ../../../libr/../shlr/sdb/sdb freebsd-x86-32.sdb =
/bin/sh gen.sh < openbsd-x86-32 | ../../../libr/../shlr/sdb/sdb openbsd-x86-32.sdb =
/bin/sh gen.sh < openbsd-x86-64 | ../../../libr/../shlr/sdb/sdb openbsd-x86-64.sdb =
/bin/sh gen.sh < windows-x86-32 | ../../../libr/../shlr/sdb/sdb windows-x86-32.sdb =
/bin/sh gen.sh < windows-x86-64 | ../../../libr/../shlr/sdb/sdb windows-x86-64.sdb =
make[5]: Leaving directory `/d/Work/radare/radare2/libr/syscall/d'
make[4]: Leaving directory `/d/Work/radare/radare2/libr/syscall/d'

But it doesn't create those fails, nor spits any error or warning.

sdb_encode contains unreachable code

 57 SDB_API char *sdb_encode(const ut8 *bin, int len) {
    [...]
 59         if (!bin || len<1)
 60                 len = strlen ((const char *)bin)+1;
 61         if (len==0)
 62                 return strdup ("");
    [...]
 69 }

If len was 0 before line 59, line 60 will change it to a value >=1. Therefore, the check in line 61 will always return false. What is the intention behind this? Should lines 61 and 62 just be removed?

And why the !bin || part in the check in line 59? Is that to make the function crash if bin == NULL? In that case, shouldn't that be a seperate assertion or so instead?

"sdb - :" segfaults

$ src/sdb - :
ASAN:SIGSEGV
=================================================================
==5202==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000008 (pc 0x7f0c208b2e1a sp 0x7fff74d46978 bp 0x7fff74d469b0 T0)
    #0 0x7f0c208b2e19 (/lib/x86_64-linux-gnu/libc.so.6+0x81e19)
    #1 0x45d5e6 in __interceptor_strlen (/home/jonathan/dev/debug/r2/sdb/src/sdb+0x45d5e6)
    #2 0x493bf2 in sdb_json_indent /home/jonathan/dev/debug/r2/sdb/src/json.c:202
    #3 0x499659 in sdb_querys /home/jonathan/dev/debug/r2/sdb/src/query.c:596
    #4 0x498764 in sdb_query /home/jonathan/dev/debug/r2/sdb/src/query.c:634
    #5 0x482c52 in main /home/jonathan/dev/debug/r2/sdb/src/main.c:195
    #6 0x7f0c20852b44 (/lib/x86_64-linux-gnu/libc.so.6+0x21b44)
    #7 0x4822fc in _start (/home/jonathan/dev/debug/r2/sdb/src/sdb+0x4822fc)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV ??:0 ??
==5202==ABORTING

sdb_disk_unlink

the return value of unlink is not checked. I think it should read more like this:

diff --git a/shlr/sdb/src/disk.c b/shlr/sdb/src/disk.c
index 78b5245..b21d3a2 100644
--- a/shlr/sdb/src/disk.c
+++ b/shlr/sdb/src/disk.c
@@ -83,5 +83,7 @@ SDB_API int sdb_disk_finish (Sdb* s) {

 SDB_API void sdb_disk_unlink (Sdb *s) {
        if (s->dir && *(s->dir))
-               unlink (s->dir);
+               if(!unlink (s->dir)) {
+        return 1;
+       }
 }

kind regards
z

SDB Makefile has not granular configuration to package for libraries

Hello,
the SDB makefile doesn't make it easy to configure the locations of directories.
It allows for defining prefix and destdir, but would not allow to change the libs directory.
Way how is it used combined in the PFX variable makes it difficult to configure the name of the lib (/usr/lib64 for example) directory itself.

It would make packaging easier to include these possibilities in some way similiar as autoconf toolset does. It is especially needed for the LIBDIR.

Please could you consider including this patch to the upstream SDB?:
https://rebus.fedorapeople.org/SOURCES/sdb-dirs.patch

What it does it:

  • adds config.mk with variables BINDIR, LIBDIR, DATADIR. INCDIR
  • moves MANDIR, VAPIDIR to config.mk and removes DESTDIR from there
  • makes use of the DESTDIR only in the install/sysmstall/uninstall sections
  • adds the ldconfig symbolic link (needed for rpm package and I guess it is usefull elsewhere as well)

Best regards
Michal Ambroz

Obfuscated code in base64.c

I know that sdb is not a cryptographic library, but base64.c is barely readable, and filled with arbitrary constants. This makes the review painful :|

stack query is a queue

if foo=1,2, and (+)foo=0 is executed, if its behavior is like an stack the result should be foo=0,1,2, not foo=1,2,0 (as in a list append/queue). Maybe I'm wrong... I suppose it depends of the perspective xD But when you enqueue an element it goes to the last position... Therefore, what you defined as an stack behaviour is really a queue behaviour.

Fix json warnings

More info here

https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html

./json/js0n.c:26:29: warning: initializer overrides prior initialization of this
      subobject [-Winitializer-overrides]
                ['t'] = &&l_bare, ['f'] = &&l_bare, ['n'] = &&l_bare // true...
                                          ^~~~~~~~
./json/js0n.c:15:17: note: previous initialization is here
                [0 ... 255] = &&l_bad,
                              ^~~~~~~
./json/js0n.c:26:47: warning: initializer overrides prior initialization of this
      subobject [-Winitializer-overrides]
  ...['t'] = &&l_bare, ['f'] = &&l_bare, ['n'] = &&l_bare // true, false, null
                                                 ^~~~~~~~
./json/js0n.c:15:17: note: previous initialization is here
                [0 ... 255] = &&l_bad,
                              ^~~~~~~
./json/js0n.c:32:12: warning: initializer overrides prior initialization of this
      subobject [-Winitializer-overrides]
                ['\t'] = &&l_unbare, [' '] = &&l_unbare, ['\r'] = &&l_unbare...
                         ^~~~~~~~~~
./json/js0n.c:30:16: note: previous initialization is here
                [0 ... 31] = &&l_bad,
                             ^~~~~~~
./json/js0n.c:32:32: warning: initializer overrides prior initialization of this
      subobject [-Winitializer-overrides]
                ['\t'] = &&l_unbare, [' '] = &&l_unbare, ['\r'] = &&l_unbare...
                                             ^~~~~~~~~~
./json/js0n.c:31:18: note: previous initialization is here
                [32 ... 126] = &&l_loop, // could be more pedantic/validatio...
                               ^~~~~~~~
./json/js0n.c:32:53: warning: initializer overrides prior initialization of this
      subobject [-Winitializer-overrides]
  ...['\t'] = &&l_unbare, [' '] = &&l_unbare, ['\r'] = &&l_unbare, ['\n'] = &&l_u...
                                                       ^~~~~~~~~~
./json/js0n.c:30:16: note: previous initialization is here
                [0 ... 31] = &&l_bad,
                             ^~~~~~~
./json/js0n.c:32:74: warning: initializer overrides prior initialization of this
      subobject [-Winitializer-overrides]
  ...= &&l_unbare, [' '] = &&l_unbare, ['\r'] = &&l_unbare, ['\n'] = &&l_unbare,
                                                                     ^~~~~~~~~~
./json/js0n.c:30:16: note: previous initialization is here
                [0 ... 31] = &&l_bad,
                             ^~~~~~~
./json/js0n.c:33:11: warning: initializer overrides prior initialization of this
      subobject [-Winitializer-overrides]
                [','] = &&l_unbare, [']'] = &&l_unbare, ['}'] = &&l_unbare,
                        ^~~~~~~~~~
./json/js0n.c:31:18: note: previous initialization is here
                [32 ... 126] = &&l_loop, // could be more pedantic/validatio...
                               ^~~~~~~~
./json/js0n.c:33:31: warning: initializer overrides prior initialization of this
      subobject [-Winitializer-overrides]
                [','] = &&l_unbare, [']'] = &&l_unbare, ['}'] = &&l_unbare,
                                            ^~~~~~~~~~
./json/js0n.c:31:18: note: previous initialization is here
                [32 ... 126] = &&l_loop, // could be more pedantic/validatio...
                               ^~~~~~~~
./json/js0n.c:33:51: warning: initializer overrides prior initialization of this
...

Evaluate the use of warp's hash string algorithm (in D)

original code from https://github.com/facebookarchive/warp

    static size_t getHash(const(uchar)[] name)
    {
        size_t hash = 0;
        while (name.length >= size_t.sizeof)
        {
            hash = hash * 37 + *cast(size_t*)name.ptr;
            name = name[size_t.sizeof .. $];
        }
        foreach (c; name)
            hash = hash * 37 + c;
        hash ^= (hash >> 20) ^ (hash >> 12);
        return hash ^ (hash >> 7) ^ (hash >> 4);
    }

in C would be something like:

size_t getHash(const char *str) {
  size_t hash = 0, ptr = str;
  while(strlen(ptr) >= sizeof(size_t)) {
    hash = hash * 37 + *ptr;
    ptr++;
  }
  for (str = ptr; *str; str++) {
    hash = hash * 37 + *str;
  }
  hash ^= (hash >> 20) ^ (hash >> 12);
  return hash ^ (hash >> 7) ^ (hash>> 4);
}

the strlen can be optimized by checking if any of the Nth chars is null , where N is constant for sizeof (return_type), in theory this hash have less collisions, but right now we have no reproducible collisions in the current string hashing algorithm used.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.