Skip to content
Snippets Groups Projects
Commit 8eba9ce4 authored by Konstantin Osipov's avatar Konstantin Osipov
Browse files

Merge branch 'master' of github.com:tarantool/tarantool

parents 9a0ed638 427637f1
No related branches found
No related tags found
No related merge requests found
......@@ -62,3 +62,5 @@ add_library(box
lua/error.cc
lua/session.cc
${bin_sources})
# target_link_libraries(box salad)
......@@ -11,6 +11,7 @@
#include "lua/bsdsocket.h"
#include "lua/digest.h"
#include "base64.h"
#include <lib/salad/guava.h>
/*
* A special hack to cc/ld to keep symbols in an optimized binary.
......@@ -50,5 +51,6 @@ void *ffi_symbols[] = {
(void *) base64_decode,
(void *) base64_encode,
(void *) base64_bufsize,
(void *) SHA1internal
(void *) SHA1internal,
(void *) guava
};
set(lib_sources rope.c rlist.c rtree.c)
set(lib_sources rope.c rlist.c rtree.c guava.c)
set_source_files_compile_flags(${lib_sources})
add_library(salad ${lib_sources})
/*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "lib/salad/guava.h"
#include <stdint.h>
static const int64_t K = 2862933555777941757;
static const double D = 0x1.0p31;
static inline double lcg(int64_t *state)
{
return (double )((int32_t)(((uint64_t )*state >> 33) + 1)) / D;
}
int32_t
guava(int64_t state, int32_t buckets)
{
int32_t candidate = 0;
int32_t next;
while (1) {
state = K * state + 1;
next = (int32_t)((candidate + 1) / lcg(&state));
if (next >= 0 && next < buckets)
candidate = next;
else
return candidate;
}
}
#ifndef TARANTOOL_LIB_GUAVA_H_INCLUDED
#define TARANTOOL_LIB_GUAVA_H_INCLUDED
/*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <stdint.h>
#if defined(__cplusplus)
extern "C" {
#endif
int32_t
guava(int64_t state, int32_t buckets);
#if defined(__cplusplus)
} /* extern C */
#endif
#endif /* TARANTOOL_LIB_GUAVA_H_INCLUDED */
......@@ -21,9 +21,9 @@ ffi.cdef[[
/* from libc */
int snprintf(char *str, size_t size, const char *format, ...);
typedef uint32_t (*crc32_func)(uint32_t crc,
const unsigned char *buf, unsigned int len);
extern int32_t guava(int64_t state, int32_t buckets);
extern crc32_func crc32_calc;
/* base64 */
......@@ -53,13 +53,12 @@ end
local def = {
sha = { 'SHA', 20 },
-- sha1 = { 'SHA1', 20 },
sha224 = { 'SHA224', 28 },
sha256 = { 'SHA256', 32 },
sha384 = { 'SHA384', 48 },
sha512 = { 'SHA512', 64 },
md5 = { 'MD5', 16 },
md4 = { 'MD4', 16 }
md4 = { 'MD4', 16 },
}
local hexres = ffi.new('char[129]')
......@@ -131,7 +130,11 @@ local m = {
end
local r = ffi.C.SHA1internal(str, #str, nil)
return tohex(r, 20)
end
end,
guava = function(state, buckets)
return ffi.C.guava(state, buckets)
end,
}
if ssl ~= nil then
......@@ -149,7 +152,7 @@ if ssl ~= nil then
local r = ssl[hfunction](str, string.len(str), nil)
return ffi.string(r, hsize)
end
m[ pname .. '_hex' ] = function(str)
if str == nil then
str = ''
......
......@@ -193,19 +193,39 @@ digest.base64_decode(b) == s
...
digest.base64_decode(nil)
---
- error: 'builtin/digest.lua:89: Usage: digest.base64_decode(string)'
- error: 'builtin/digest.lua:88: Usage: digest.base64_decode(string)'
...
digest.base64_encode(nil)
---
- error: 'builtin/digest.lua:78: Usage: digest.base64_encode(string)'
- error: 'builtin/digest.lua:77: Usage: digest.base64_encode(string)'
...
digest.base64_encode(123)
---
- error: 'builtin/digest.lua:78: Usage: digest.base64_encode(string)'
- error: 'builtin/digest.lua:77: Usage: digest.base64_encode(string)'
...
digest.base64_decode(123)
---
- error: 'builtin/digest.lua:89: Usage: digest.base64_decode(string)'
- error: 'builtin/digest.lua:88: Usage: digest.base64_decode(string)'
...
digest.guava('hello', 0)
---
- error: 'bad argument #1 to ''?'' (cannot convert ''string'' to ''int64_t'')'
...
digest.guava(1, 'nope_')
---
- error: 'bad argument #2 to ''?'' (cannot convert ''string'' to ''int'')'
...
digest.guava(10863919174838991, 11)
---
- 8
...
digest.guava(2016238256797177309, 11)
---
- 7
...
digest.guava(1673758223894951030, 11)
---
- 7
...
digest = nil
---
......
......@@ -59,4 +59,10 @@ digest.base64_encode(nil)
digest.base64_encode(123)
digest.base64_decode(123)
digest.guava('hello', 0)
digest.guava(1, 'nope_')
digest.guava(10863919174838991, 11)
digest.guava(2016238256797177309, 11)
digest.guava(1673758223894951030, 11)
digest = nil
......@@ -73,3 +73,6 @@ add_executable(scramble.test scramble.c
${CMAKE_SOURCE_DIR}/third_party/sha1.c
${CMAKE_SOURCE_DIR}/third_party/base64.c
${CMAKE_SOURCE_DIR}/src/random.c)
add_executable(guava.test guava.c)
target_link_libraries(guava.test salad)
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "unit.h"
#include "salad/guava.h"
static void
check_guava_correctness(uint64_t code)
{
int32_t last = 0;
for (int32_t shards = 1; shards <= 100000; shards++) {
int32_t b = guava(code, shards);
if (b != last) {
fail_if(shards - 1 != b);
last = b;
}
}
}
static void
correctness_check()
{
header();
int64_t i_vals[] = {0, 1, 2};
for (size_t i = 0; i < sizeof(i_vals) / sizeof(int64_t); ++i)
check_guava_correctness(i_vals[i]);
srand(time(NULL));
for (size_t i = 0; i < 20; ++i)
check_guava_correctness(rand() % 7);
footer();
}
static void
sameresult_check()
{
header();
fail_if(guava(100, 20) != guava(100, 20));
footer();
}
static void
lcg_compat_check()
{
header();
int32_t golden100[] = {
0, 55, 62, 8, 45, 59, 86, 97, 82, 59,
73, 37, 17, 56, 86, 21, 90, 37, 38, 83
};
for (size_t i = 0; i < sizeof(golden100) / sizeof(int64_t); ++i)
check_guava_correctness(golden100[i]);
fail_if(6 != guava(10863919174838991ULL, 11));
fail_if(3 != guava(2016238256797177309ULL, 11));
fail_if(5 != guava(1673758223894951030ULL, 11));
fail_if(80343 != guava(2, 100001));
fail_if(22152 != guava(2201, 100001));
fail_if(15018 != guava(2202, 100001));
footer();
}
int
main(void)
{
correctness_check();
lcg_compat_check();
sameresult_check();
}
*** correctness_check ***
*** correctness_check: done ***
*** lcg_compat_check ***
*** lcg_compat_check: done ***
*** sameresult_check ***
*** sameresult_check: done ***
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment