Commit b7650cdd authored by Pavel Vainerman's avatar Pavel Vainerman Committed by Pavel Vainerman

supported hash[32|64], added 3rd party library (contrib)

parent f7a26056
......@@ -3,7 +3,7 @@
############################################################################
FIRSTSUBDIRS=IDL
SUBDIRS=. src lib include Utilities tests extensions wrappers docs
SUBDIRS=. contrib src lib include Utilities tests extensions wrappers docs
# testsuite
pkgconfigdir = $(libdir)/pkgconfig
......
......@@ -274,7 +274,6 @@ fi
AM_CONDITIONAL(HAVE_EXTENTIONS, test ${ext} = true)
#check python support
AC_MSG_CHECKING([python support])
buildpython=true
......@@ -376,7 +375,7 @@ fi
AC_MSG_CHECKING([catch version in $CATCH_FILE])
CATCH_RESULT=
if cat ${CATCH_FILE} | grep -q "Catch v2."; then
CATCH_VERSION_MAJOR=2;
CATCH_VERSION_MAJOR=2;
fi
AC_MSG_RESULT([$CATCH_VERSION_MAJOR])
......@@ -531,6 +530,9 @@ AC_CONFIG_FILES([Makefile
IDL/UniSetTypes/Makefile
IDL/UniSetTypes/UniSetBaseConstants.idl
IDL/Processes/Makefile
contrib/Makefile
contrib/cityhash102/Makefile
contrib/libfarmhash/Makefile
src/Core/Makefile
src/Communications/Makefile
src/Communications/Modbus/Makefile
......
############################################################################
# This file is part of the UniSet library #
############################################################################
SUBDIRS=cityhash102 libfarmhash
include $(top_builddir)/include.mk
// Copyright (c) 2011 Google, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
noinst_LTLIBRARIES = libCityHash102.la
libCityHash102_la_CPPFLAGS = -Isrc -Iinclude
libCityHash102_la_SOURCES = src/city.cc
include $(top_builddir)/include.mk
// Copyright (c) 2011 Google, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// CityHash, by Geoff Pike and Jyrki Alakuijala
//
// This file provides a few functions for hashing strings. On x86-64
// hardware in 2011, CityHash64() is faster than other high-quality
// hash functions, such as Murmur. This is largely due to higher
// instruction-level parallelism. CityHash64() and CityHash128() also perform
// well on hash-quality tests.
//
// CityHash128() is optimized for relatively long strings and returns
// a 128-bit hash. For strings more than about 2000 bytes it can be
// faster than CityHash64().
//
// Functions in the CityHash family are not suitable for cryptography.
//
// WARNING: This code has not been tested on big-endian platforms!
// It is known to work well on little-endian platforms that have a small penalty
// for unaligned reads, such as current Intel and AMD moderate-to-high-end CPUs.
//
// By the way, for some hash functions, given strings a and b, the hash
// of a+b is easily derived from the hashes of a and b. This property
// doesn't hold for any hash functions in this file.
#ifndef CITY_HASH_H_
#define CITY_HASH_H_
#include <stdlib.h> // for size_t.
#include <stdint.h>
#include <utility>
/** This is a version of CityHash that predates v1.0.3 algorithm change.
* Why we need exactly this version?
* Although hash values of CityHash are not recommended for storing persistently anywhere,
* it has already been used this way in ClickHouse:
* - for calculation of checksums of compressed chunks and for data parts;
* - this version of CityHash is exposed in cityHash64 function in ClickHouse SQL language;
* - and already used by many users for data ordering, sampling and sharding.
*/
namespace CityHash_v1_0_2
{
typedef uint8_t uint8;
typedef uint32_t uint32;
typedef uint64_t uint64;
typedef std::pair<uint64, uint64> uint128;
inline uint64 Uint128Low64(const uint128& x) { return x.first; }
inline uint64 Uint128High64(const uint128& x) { return x.second; }
// Hash function for a byte array.
uint64 CityHash64(const char *buf, size_t len);
// Hash function for a byte array. For convenience, a 64-bit seed is also
// hashed into the result.
uint64 CityHash64WithSeed(const char *buf, size_t len, uint64 seed);
// Hash function for a byte array. For convenience, two seeds are also
// hashed into the result.
uint64 CityHash64WithSeeds(const char *buf, size_t len,
uint64 seed0, uint64 seed1);
// Hash function for a byte array.
uint128 CityHash128(const char *s, size_t len);
// Hash function for a byte array. For convenience, a 128-bit seed is also
// hashed into the result.
uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed);
// Hash 128 input bits down to 64 bits of output.
// This is intended to be a reasonably good hash function.
inline uint64 Hash128to64(const uint128& x) {
// Murmur-inspired hashing.
const uint64 kMul = 0x9ddfea08eb382d69ULL;
uint64 a = (Uint128Low64(x) ^ Uint128High64(x)) * kMul;
a ^= (a >> 47);
uint64 b = (Uint128High64(x) ^ a) * kMul;
b ^= (b >> 47);
b *= kMul;
return b;
}
}
#endif // CITY_HASH_H_
// Copyright (c) 2011 Google, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// CityHash, by Geoff Pike and Jyrki Alakuijala
//
// This file declares the subset of the CityHash functions that require
// _mm_crc32_u64(). See the CityHash README for details.
//
// Functions in the CityHash family are not suitable for cryptography.
#ifndef CITY_HASH_CRC_H_
#define CITY_HASH_CRC_H_
#include <city.h>
namespace CityHash_v1_0_2
{
// Hash function for a byte array.
uint128 CityHashCrc128(const char *s, size_t len);
// Hash function for a byte array. For convenience, a 128-bit seed is also
// hashed into the result.
uint128 CityHashCrc128WithSeed(const char *s, size_t len, uint128 seed);
// Hash function for a byte array. Sets result[0] ... result[3].
void CityHashCrc256(const char *s, size_t len, uint64 *result);
}
#endif // CITY_HASH_CRC_H_
// Copyright (c) 2011 Google, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// CityHash, by Geoff Pike and Jyrki Alakuijala
//
// This file provides CityHash64() and related functions.
//
// It's probably possible to create even faster hash functions by
// writing a program that systematically explores some of the space of
// possible hash functions, by using SIMD instructions, or by
// compromising on hash quality.
#include "config.h"
#include <city.h>
#include <algorithm>
#include <string.h> // for memcpy and memset
using namespace std;
#if !defined(WORDS_BIGENDIAN)
#define uint32_in_expected_order(x) (x)
#define uint64_in_expected_order(x) (x)
#else
#ifdef _MSC_VER
#include <stdlib.h>
#define bswap_32(x) _byteswap_ulong(x)
#define bswap_64(x) _byteswap_uint64(x)
#elif defined(__APPLE__)
// Mac OS X / Darwin features
#include <libkern/OSByteOrder.h>
#define bswap_32(x) OSSwapInt32(x)
#define bswap_64(x) OSSwapInt64(x)
#else
#include <byteswap.h>
#endif
#define uint32_in_expected_order(x) (bswap_32(x))
#define uint64_in_expected_order(x) (bswap_64(x))
#endif // WORDS_BIGENDIAN
#if !defined(LIKELY)
#if HAVE_BUILTIN_EXPECT
#define LIKELY(x) (__builtin_expect(!!(x), 1))
#else
#define LIKELY(x) (x)
#endif
#endif
namespace CityHash_v1_0_2
{
static uint64 UNALIGNED_LOAD64(const char *p) {
uint64 result;
memcpy(&result, p, sizeof(result));
return result;
}
static uint32 UNALIGNED_LOAD32(const char *p) {
uint32 result;
memcpy(&result, p, sizeof(result));
return result;
}
static uint64 Fetch64(const char *p) {
return uint64_in_expected_order(UNALIGNED_LOAD64(p));
}
static uint32 Fetch32(const char *p) {
return uint32_in_expected_order(UNALIGNED_LOAD32(p));
}
// Some primes between 2^63 and 2^64 for various uses.
static const uint64 k0 = 0xc3a5c85c97cb3127ULL;
static const uint64 k1 = 0xb492b66fbe98f273ULL;
static const uint64 k2 = 0x9ae16a3b2f90404fULL;
static const uint64 k3 = 0xc949d7c7509e6557ULL;
// Bitwise right rotate. Normally this will compile to a single
// instruction, especially if the shift is a manifest constant.
static uint64 Rotate(uint64 val, int shift) {
// Avoid shifting by 64: doing so yields an undefined result.
return shift == 0 ? val : ((val >> shift) | (val << (64 - shift)));
}
// Equivalent to Rotate(), but requires the second arg to be non-zero.
// On x86-64, and probably others, it's possible for this to compile
// to a single instruction if both args are already in registers.
static uint64 RotateByAtLeast1(uint64 val, int shift) {
return (val >> shift) | (val << (64 - shift));
}
static uint64 ShiftMix(uint64 val) {
return val ^ (val >> 47);
}
static uint64 HashLen16(uint64 u, uint64 v) {
return Hash128to64(uint128(u, v));
}
static uint64 HashLen0to16(const char *s, size_t len) {
if (len > 8) {
uint64 a = Fetch64(s);
uint64 b = Fetch64(s + len - 8);
return HashLen16(a, RotateByAtLeast1(b + len, len)) ^ b;
}
if (len >= 4) {
uint64 a = Fetch32(s);
return HashLen16(len + (a << 3), Fetch32(s + len - 4));
}
if (len > 0) {
uint8 a = s[0];
uint8 b = s[len >> 1];
uint8 c = s[len - 1];
uint32 y = static_cast<uint32>(a) + (static_cast<uint32>(b) << 8);
uint32 z = len + (static_cast<uint32>(c) << 2);
return ShiftMix(y * k2 ^ z * k3) * k2;
}
return k2;
}
// This probably works well for 16-byte strings as well, but it may be overkill
// in that case.
static uint64 HashLen17to32(const char *s, size_t len) {
uint64 a = Fetch64(s) * k1;
uint64 b = Fetch64(s + 8);
uint64 c = Fetch64(s + len - 8) * k2;
uint64 d = Fetch64(s + len - 16) * k0;
return HashLen16(Rotate(a - b, 43) + Rotate(c, 30) + d,
a + Rotate(b ^ k3, 20) - c + len);
}
// Return a 16-byte hash for 48 bytes. Quick and dirty.
// Callers do best to use "random-looking" values for a and b.
static pair<uint64, uint64> WeakHashLen32WithSeeds(
uint64 w, uint64 x, uint64 y, uint64 z, uint64 a, uint64 b) {
a += w;
b = Rotate(b + a + z, 21);
uint64 c = a;
a += x;
a += y;
b += Rotate(a, 44);
return make_pair(a + z, b + c);
}
// Return a 16-byte hash for s[0] ... s[31], a, and b. Quick and dirty.
static pair<uint64, uint64> WeakHashLen32WithSeeds(
const char* s, uint64 a, uint64 b) {
return WeakHashLen32WithSeeds(Fetch64(s),
Fetch64(s + 8),
Fetch64(s + 16),
Fetch64(s + 24),
a,
b);
}
// Return an 8-byte hash for 33 to 64 bytes.
static uint64 HashLen33to64(const char *s, size_t len) {
uint64 z = Fetch64(s + 24);
uint64 a = Fetch64(s) + (len + Fetch64(s + len - 16)) * k0;
uint64 b = Rotate(a + z, 52);
uint64 c = Rotate(a, 37);
a += Fetch64(s + 8);
c += Rotate(a, 7);
a += Fetch64(s + 16);
uint64 vf = a + z;
uint64 vs = b + Rotate(a, 31) + c;
a = Fetch64(s + 16) + Fetch64(s + len - 32);
z = Fetch64(s + len - 8);
b = Rotate(a + z, 52);
c = Rotate(a, 37);
a += Fetch64(s + len - 24);
c += Rotate(a, 7);
a += Fetch64(s + len - 16);
uint64 wf = a + z;
uint64 ws = b + Rotate(a, 31) + c;
uint64 r = ShiftMix((vf + ws) * k2 + (wf + vs) * k0);
return ShiftMix(r * k0 + vs) * k2;
}
uint64 CityHash64(const char *s, size_t len) {
if (len <= 32) {
if (len <= 16) {
return HashLen0to16(s, len);
} else {
return HashLen17to32(s, len);
}
} else if (len <= 64) {
return HashLen33to64(s, len);
}
// For strings over 64 bytes we hash the end first, and then as we
// loop we keep 56 bytes of state: v, w, x, y, and z.
uint64 x = Fetch64(s);
uint64 y = Fetch64(s + len - 16) ^ k1;
uint64 z = Fetch64(s + len - 56) ^ k0;
pair<uint64, uint64> v = WeakHashLen32WithSeeds(s + len - 64, len, y);
pair<uint64, uint64> w = WeakHashLen32WithSeeds(s + len - 32, len * k1, k0);
z += ShiftMix(v.second) * k1;
x = Rotate(z + x, 39) * k1;
y = Rotate(y, 33) * k1;
// Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
len = (len - 1) & ~static_cast<size_t>(63);
do {
x = Rotate(x + y + v.first + Fetch64(s + 16), 37) * k1;
y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1;
x ^= w.second;
y ^= v.first;
z = Rotate(z ^ w.first, 33);
v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
w = WeakHashLen32WithSeeds(s + 32, z + w.second, y);
std::swap(z, x);
s += 64;
len -= 64;
} while (len != 0);
return HashLen16(HashLen16(v.first, w.first) + ShiftMix(y) * k1 + z,
HashLen16(v.second, w.second) + x);
}
uint64 CityHash64WithSeed(const char *s, size_t len, uint64 seed) {
return CityHash64WithSeeds(s, len, k2, seed);
}
uint64 CityHash64WithSeeds(const char *s, size_t len,
uint64 seed0, uint64 seed1) {
return HashLen16(CityHash64(s, len) - seed0, seed1);
}
// A subroutine for CityHash128(). Returns a decent 128-bit hash for strings
// of any length representable in ssize_t. Based on City and Murmur.
static uint128 CityMurmur(const char *s, size_t len, uint128 seed) {
uint64 a = Uint128Low64(seed);
uint64 b = Uint128High64(seed);
uint64 c = 0;
uint64 d = 0;
ssize_t l = len - 16;
if (l <= 0) { // len <= 16
a = ShiftMix(a * k1) * k1;
c = b * k1 + HashLen0to16(s, len);
d = ShiftMix(a + (len >= 8 ? Fetch64(s) : c));
} else { // len > 16
c = HashLen16(Fetch64(s + len - 8) + k1, a);
d = HashLen16(b + len, c + Fetch64(s + len - 16));
a += d;
do {
a ^= ShiftMix(Fetch64(s) * k1) * k1;
a *= k1;
b ^= a;
c ^= ShiftMix(Fetch64(s + 8) * k1) * k1;
c *= k1;
d ^= c;
s += 16;
l -= 16;
} while (l > 0);
}
a = HashLen16(a, c);
b = HashLen16(d, b);
return uint128(a ^ b, HashLen16(b, a));
}
uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed) {
if (len < 128) {
return CityMurmur(s, len, seed);
}
// We expect len >= 128 to be the common case. Keep 56 bytes of state:
// v, w, x, y, and z.
pair<uint64, uint64> v, w;
uint64 x = Uint128Low64(seed);
uint64 y = Uint128High64(seed);
uint64 z = len * k1;
v.first = Rotate(y ^ k1, 49) * k1 + Fetch64(s);
v.second = Rotate(v.first, 42) * k1 + Fetch64(s + 8);
w.first = Rotate(y + z, 35) * k1 + x;
w.second = Rotate(x + Fetch64(s + 88), 53) * k1;
// This is the same inner loop as CityHash64(), manually unrolled.
do {
x = Rotate(x + y + v.first + Fetch64(s + 16), 37) * k1;
y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1;
x ^= w.second;
y ^= v.first;
z = Rotate(z ^ w.first, 33);
v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
w = WeakHashLen32WithSeeds(s + 32, z + w.second, y);
std::swap(z, x);
s += 64;
x = Rotate(x + y + v.first + Fetch64(s + 16), 37) * k1;
y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1;
x ^= w.second;
y ^= v.first;
z = Rotate(z ^ w.first, 33);
v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
w = WeakHashLen32WithSeeds(s + 32, z + w.second, y);
std::swap(z, x);
s += 64;
len -= 128;
} while (LIKELY(len >= 128));
y += Rotate(w.first, 37) * k0 + z;
x += Rotate(v.first + z, 49) * k0;
// If 0 < len < 128, hash up to 4 chunks of 32 bytes each from the end of s.
for (size_t tail_done = 0; tail_done < len; ) {
tail_done += 32;
y = Rotate(y - x, 42) * k0 + v.second;
w.first += Fetch64(s + len - tail_done + 16);
x = Rotate(x, 49) * k0 + w.first;
w.first += v.first;
v = WeakHashLen32WithSeeds(s + len - tail_done, v.first, v.second);
}
// At this point our 48 bytes of state should contain more than
// enough information for a strong 128-bit hash. We use two
// different 48-byte-to-8-byte hashes to get a 16-byte final result.
x = HashLen16(x, v.first);
y = HashLen16(y, w.first);
return uint128(HashLen16(x + v.second, w.second) + y,
HashLen16(x + w.second, y + v.second));
}
uint128 CityHash128(const char *s, size_t len) {
if (len >= 16) {
return CityHash128WithSeed(s + 16,
len - 16,
uint128(Fetch64(s) ^ k3,
Fetch64(s + 8)));
} else if (len >= 8) {
return CityHash128WithSeed(NULL,
0,
uint128(Fetch64(s) ^ (len * k0),
Fetch64(s + len - 8) ^ k1));
} else {
return CityHash128WithSeed(s, len, uint128(k0, k1));
}
}
}
#ifdef __SSE4_2__
#include <citycrc.h>
#include <nmmintrin.h>
namespace CityHash_v1_0_2
{
// Requires len >= 240.
static void CityHashCrc256Long(const char *s, size_t len,
uint32 seed, uint64 *result) {
uint64 a = Fetch64(s + 56) + k0;
uint64 b = Fetch64(s + 96) + k0;
uint64 c = result[1] = HashLen16(b, len);
uint64 d = result[2] = Fetch64(s + 120) * k0 + len;
uint64 e = Fetch64(s + 184) + seed;
uint64 f = seed;
uint64 g = 0;
uint64 h = 0;
uint64 i = 0;
uint64 j = 0;
uint64 t = c + d;
// 240 bytes of input per iter.
size_t iters = len / 240;
len -= iters * 240;
do {
#define CHUNK(multiplier, z) \
{ \
uint64 old_a = a; \
a = Rotate(b, 41 ^ z) * multiplier + Fetch64(s); \
b = Rotate(c, 27 ^ z) * multiplier + Fetch64(s + 8); \
c = Rotate(d, 41 ^ z) * multiplier + Fetch64(s + 16); \
d = Rotate(e, 33 ^ z) * multiplier + Fetch64(s + 24); \
e = Rotate(t, 25 ^ z) * multiplier + Fetch64(s + 32); \
t = old_a; \
} \
f = _mm_crc32_u64(f, a); \
g = _mm_crc32_u64(g, b); \
h = _mm_crc32_u64(h, c); \
i = _mm_crc32_u64(i, d); \
j = _mm_crc32_u64(j, e); \
s += 40
CHUNK(1, 1); CHUNK(k0, 0);
CHUNK(1, 1); CHUNK(k0, 0);
CHUNK(1, 1); CHUNK(k0, 0);
} while (--iters > 0);
j += i << 32;
a = HashLen16(a, j);
h += g << 32;
b = b * k0 + h;
c = HashLen16(c, f) + i;
d = HashLen16(d, e);
pair<uint64, uint64> v(j + e, HashLen16(h, t));
h = v.second + f;
// If 0 < len < 240, hash chunks of 32 bytes each from the end of s.
for (size_t tail_done = 0; tail_done < len; ) {
tail_done += 32;
c = Rotate(c - a, 42) * k0 + v.second;
d += Fetch64(s + len - tail_done + 16);
a = Rotate(a, 49) * k0 + d;
d += v.first;
v = WeakHashLen32WithSeeds(s + len - tail_done, v.first, v.second);
}
// Final mix.
e = HashLen16(a, d) + v.first;
f = HashLen16(b, c) + a;
g = HashLen16(v.first, v.second) + c;
result[0] = e + f + g + h;
a = ShiftMix((a + g) * k0) * k0 + b;
result[1] += a + result[0];
a = ShiftMix(a * k0) * k0 + c;
result[2] += a + result[1];
a = ShiftMix((a + e) * k0) * k0;
result[3] = a + result[2];
}
// Requires len < 240.
static void CityHashCrc256Short(const char *s, size_t len, uint64 *result) {
char buf[240];
memcpy(buf, s, len);
memset(buf + len, 0, 240 - len);
CityHashCrc256Long(buf, 240, ~static_cast<uint32>(len), result);
}
void CityHashCrc256(const char *s, size_t len, uint64 *result) {
if (LIKELY(len >= 240)) {
CityHashCrc256Long(s, len, 0, result);
} else {
CityHashCrc256Short(s, len, result);
}
}
uint128 CityHashCrc128WithSeed(const char *s, size_t len, uint128 seed) {
if (len <= 900) {
return CityHash128WithSeed(s, len, seed);
} else {
uint64 result[4];
CityHashCrc256(s, len, result);
uint64 u = Uint128High64(seed) + result[0];
uint64 v = Uint128Low64(seed) + result[1];
return uint128(HashLen16(u, v + result[2]),
HashLen16(Rotate(v, 32), u * k0 + result[3]));
}
}
uint128 CityHashCrc128(const char *s, size_t len) {
if (len <= 900) {
return CityHash128(s, len);
} else {
uint64 result[4];
CityHashCrc256(s, len, result);
return uint128(result[2], result[3]);
}
}
}
#endif
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* Define to 1 if the compiler supports __builtin_expect. */
#if _MSC_VER
#define HAVE_BUILTIN_EXPECT 0
#else
#define HAVE_BUILTIN_EXPECT 1
#endif
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "cityhash-discuss@googlegroups.com"
/* Define to the full name of this package. */
#define PACKAGE_NAME "CityHash"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "CityHash 1.0.2"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "cityhash"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "1.0.2"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
/* #undef _UINT32_T */
/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
/* #undef _UINT64_T */
/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
/* #undef _UINT8_T */
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* #undef inline */
#endif
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
/* Define to `int' if <sys/types.h> does not define. */
/* #undef ssize_t */
/* Define to the type of an unsigned integer type of width exactly 32 bits if
such a type exists and the standard includes do not define it. */
/* #undef uint32_t */
/* Define to the type of an unsigned integer type of width exactly 64 bits if
such a type exists and the standard includes do not define it. */
/* #undef uint64_t */
/* Define to the type of an unsigned integer type of width exactly 8 bits if
such a type exists and the standard includes do not define it. */
/* #undef uint8_t */
#ifdef _MSC_VER
#include <basetsd.h>
typedef SSIZE_T ssize_t;
#else
#include <sys/types.h>
#endif
// Copyright (c) 2014 Google, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
noinst_LTLIBRARIES = libFarmHash.la
libFarmHash_la_SOURCES = farmhash.cc
include $(top_builddir)/include.mk
Original URL: https://code.google.com/p/farmhash/
Created from version:
commit afdb2e459d030afd1f3b6116545397509326385e
Author: gpike@google.com <gpike@google.com@34f43262-9e73-f86a-efff-89e1528fadaf>
Date: Sun Mar 1 20:04:23 2015 +0000
Various additions, updates, and fixes for FarmHash 1.1.
This source diff could not be displayed because it is too large. You can view the blob instead.
// Copyright (c) 2014 Google, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// FarmHash, by Geoff Pike
//
// http://code.google.com/p/farmhash/
//
// This file provides a few functions for hashing strings and other
// data. All of them are high-quality functions in the sense that
// they do well on standard tests such as Austin Appleby's SMHasher.
// They're also fast. FarmHash is the successor to CityHash.
//
// Functions in the FarmHash family are not suitable for cryptography.
//
// WARNING: This code has been only lightly tested on big-endian platforms!
// It is known to work well on little-endian platforms that have a small penalty
// for unaligned reads, such as current Intel and AMD moderate-to-high-end CPUs.
// It should work on all 32-bit and 64-bit platforms that allow unaligned reads;
// bug reports are welcome.
//
// By the way, for some hash functions, given strings a and b, the hash
// of a+b is easily derived from the hashes of a and b. This property
// doesn't hold for any hash functions in this file.
#ifndef FARM_HASH_H_
#define FARM_HASH_H_
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h> // for memcpy and memset
#include <utility>
#ifndef NAMESPACE_FOR_HASH_FUNCTIONS
#define NAMESPACE_FOR_HASH_FUNCTIONS farmhash
#endif
namespace NAMESPACE_FOR_HASH_FUNCTIONS {
#if defined(FARMHASH_UINT128_T_DEFINED)
inline uint64_t Uint128Low64(const uint128_t x) {
return static_cast<uint64_t>(x);
}
inline uint64_t Uint128High64(const uint128_t x) {
return static_cast<uint64_t>(x >> 64);
}
inline uint128_t Uint128(uint64_t lo, uint64_t hi) {
return lo + (((uint128_t)hi) << 64);
}
#else
typedef std::pair<uint64_t, uint64_t> uint128_t;
inline uint64_t Uint128Low64(const uint128_t x) { return x.first; }
inline uint64_t Uint128High64(const uint128_t x) { return x.second; }
inline uint128_t Uint128(uint64_t lo, uint64_t hi) { return uint128_t(lo, hi); }
#endif
// BASIC STRING HASHING
// Hash function for a byte array.
// May change from time to time, may differ on different platforms, may differ
// depending on NDEBUG.
size_t Hash(const char* s, size_t len);
// Hash function for a byte array. Most useful in 32-bit binaries.
// May change from time to time, may differ on different platforms, may differ
// depending on NDEBUG.
uint32_t Hash32(const char* s, size_t len);
// Hash function for a byte array. For convenience, a 32-bit seed is also
// hashed into the result.
// May change from time to time, may differ on different platforms, may differ
// depending on NDEBUG.
uint32_t Hash32WithSeed(const char* s, size_t len, uint32_t seed);
// Hash 128 input bits down to 64 bits of output.
// Hash function for a byte array.
// May change from time to time, may differ on different platforms, may differ
// depending on NDEBUG.
uint64_t Hash64(const char* s, size_t len);
// Hash function for a byte array. For convenience, a 64-bit seed is also
// hashed into the result.
// May change from time to time, may differ on different platforms, may differ
// depending on NDEBUG.
uint64_t Hash64WithSeed(const char* s, size_t len, uint64_t seed);
// Hash function for a byte array. For convenience, two seeds are also
// hashed into the result.
// May change from time to time, may differ on different platforms, may differ
// depending on NDEBUG.
uint64_t Hash64WithSeeds(const char* s, size_t len,
uint64_t seed0, uint64_t seed1);
// Hash function for a byte array.
// May change from time to time, may differ on different platforms, may differ
// depending on NDEBUG.
uint128_t Hash128(const char* s, size_t len);
// Hash function for a byte array. For convenience, a 128-bit seed is also
// hashed into the result.
// May change from time to time, may differ on different platforms, may differ
// depending on NDEBUG.
uint128_t Hash128WithSeed(const char* s, size_t len, uint128_t seed);
// BASIC NON-STRING HASHING
// This is intended to be a reasonably good hash function.
// May change from time to time, may differ on different platforms, may differ
// depending on NDEBUG.
inline uint64_t Hash128to64(uint128_t x) {
// Murmur-inspired hashing.
const uint64_t kMul = 0x9ddfea08eb382d69ULL;
uint64_t a = (Uint128Low64(x) ^ Uint128High64(x)) * kMul;
a ^= (a >> 47);
uint64_t b = (Uint128High64(x) ^ a) * kMul;
b ^= (b >> 47);
b *= kMul;
return b;
}
// FINGERPRINTING (i.e., good, portable, forever-fixed hash functions)
// Fingerprint function for a byte array. Most useful in 32-bit binaries.
uint32_t Fingerprint32(const char* s, size_t len);
// Fingerprint function for a byte array.
uint64_t Fingerprint64(const char* s, size_t len);
// Fingerprint function for a byte array.
uint128_t Fingerprint128(const char* s, size_t len);
// This is intended to be a good fingerprinting primitive.
// See below for more overloads.
inline uint64_t Fingerprint(uint128_t x) {
// Murmur-inspired hashing.
const uint64_t kMul = 0x9ddfea08eb382d69ULL;
uint64_t a = (Uint128Low64(x) ^ Uint128High64(x)) * kMul;
a ^= (a >> 47);
uint64_t b = (Uint128High64(x) ^ a) * kMul;
b ^= (b >> 44);
b *= kMul;
b ^= (b >> 41);
b *= kMul;
return b;
}
// This is intended to be a good fingerprinting primitive.
inline uint64_t Fingerprint(uint64_t x) {
// Murmur-inspired hashing.
const uint64_t kMul = 0x9ddfea08eb382d69ULL;
uint64_t b = x * kMul;
b ^= (b >> 44);
b *= kMul;
b ^= (b >> 41);
b *= kMul;
return b;
}
#ifndef FARMHASH_NO_CXX_STRING
// Convenience functions to hash or fingerprint C++ strings.
// These require that Str::data() return a pointer to the first char
// (as a const char*) and that Str::length() return the string's length;
// they work with std::string, for example.
// Hash function for a byte array.
// May change from time to time, may differ on different platforms, may differ
// depending on NDEBUG.
template <typename Str>
inline size_t Hash(const Str& s) {
assert(sizeof(s[0]) == 1);
return Hash(s.data(), s.length());
}
// Hash function for a byte array. Most useful in 32-bit binaries.
// May change from time to time, may differ on different platforms, may differ
// depending on NDEBUG.
template <typename Str>
inline uint32_t Hash32(const Str& s) {
assert(sizeof(s[0]) == 1);
return Hash32(s.data(), s.length());
}
// Hash function for a byte array. For convenience, a 32-bit seed is also
// hashed into the result.
// May change from time to time, may differ on different platforms, may differ
// depending on NDEBUG.
template <typename Str>
inline uint32_t Hash32WithSeed(const Str& s, uint32_t seed) {
assert(sizeof(s[0]) == 1);
return Hash32WithSeed(s.data(), s.length(), seed);
}
// Hash 128 input bits down to 64 bits of output.
// Hash function for a byte array.
// May change from time to time, may differ on different platforms, may differ
// depending on NDEBUG.
template <typename Str>
inline uint64_t Hash64(const Str& s) {
assert(sizeof(s[0]) == 1);
return Hash64(s.data(), s.length());
}
// Hash function for a byte array. For convenience, a 64-bit seed is also
// hashed into the result.
// May change from time to time, may differ on different platforms, may differ
// depending on NDEBUG.
template <typename Str>
inline uint64_t Hash64WithSeed(const Str& s, uint64_t seed) {
assert(sizeof(s[0]) == 1);
return Hash64WithSeed(s.data(), s.length(), seed);
}
// Hash function for a byte array. For convenience, two seeds are also
// hashed into the result.
// May change from time to time, may differ on different platforms, may differ
// depending on NDEBUG.
template <typename Str>
inline uint64_t Hash64WithSeeds(const Str& s, uint64_t seed0, uint64_t seed1) {
assert(sizeof(s[0]) == 1);
return Hash64WithSeeds(s.data(), s.length(), seed0, seed1);
}
// Hash function for a byte array.
// May change from time to time, may differ on different platforms, may differ
// depending on NDEBUG.
template <typename Str>
inline uint128_t Hash128(const Str& s) {
assert(sizeof(s[0]) == 1);
return Hash128(s.data(), s.length());
}
// Hash function for a byte array. For convenience, a 128-bit seed is also
// hashed into the result.
// May change from time to time, may differ on different platforms, may differ
// depending on NDEBUG.
template <typename Str>
inline uint128_t Hash128WithSeed(const Str& s, uint128_t seed) {
assert(sizeof(s[0]) == 1);
return Hash128(s.data(), s.length(), seed);
}
// FINGERPRINTING (i.e., good, portable, forever-fixed hash functions)
// Fingerprint function for a byte array. Most useful in 32-bit binaries.
template <typename Str>
inline uint32_t Fingerprint32(const Str& s) {
assert(sizeof(s[0]) == 1);
return Fingerprint32(s.data(), s.length());
}
// Fingerprint 128 input bits down to 64 bits of output.
// Fingerprint function for a byte array.
template <typename Str>
inline uint64_t Fingerprint64(const Str& s) {
assert(sizeof(s[0]) == 1);
return Fingerprint64(s.data(), s.length());
}
// Fingerprint function for a byte array.
template <typename Str>
inline uint128_t Fingerprint128(const Str& s) {
assert(sizeof(s[0]) == 1);
return Fingerprint128(s.data(), s.length());
}
#endif
} // namespace NAMESPACE_FOR_HASH_FUNCTIONS
#endif // FARM_HASH_H_
CREATE TABLE main_history (
id PRIMARY KEY NOT NULL,
id BIGSERIAL PRIMARY KEY NOT NULL,
date date NOT NULL,
time time NOT NULL,
time_usec int NOT NULL CHECK (time_usec >= 0),
sensor_id int NOT NULL,
value double precision NOT NULL,
node int NOT NULL,
confirm int DEFAULT NULL,
PRIMARY KEY (id)
confirm int DEFAULT NULL
);
......@@ -32,6 +32,7 @@ namespace uniset
{
/*! реализация интерфейса ObjectIndex на основе xml-файла, с автоматическим назначением id объектам
* DEPRECATED! Use ObjectIndex_hashXML!
*
* \todo Проверить функции этого класса на повторную входимость
*/
......
/*
* Copyright (c) 2020 Pavel Vainerman.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, version 2.1.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Lesser Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// --------------------------------------------------------------------------
#ifndef ObjectIndex_hashXML_H_
#define ObjectIndex_hashXML_H_
// --------------------------------------------------------------------------
#include <unordered_map>
#include <string>
#include "ObjectIndex.h"
#include "UniXML.h"
// --------------------------------------------------------------------------
namespace uniset
{
/*! реализация интерфейса ObjectIndex на основе xml-файла,
* с генерированием id на основе name при помощи hash функции
*/
class ObjectIndex_hashXML:
public uniset::ObjectIndex
{
public:
ObjectIndex_hashXML( const std::string& xmlfile );
ObjectIndex_hashXML( const std::shared_ptr<UniXML>& xml );
virtual ~ObjectIndex_hashXML();
virtual const uniset::ObjectInfo* getObjectInfo( const uniset::ObjectId ) const noexcept override;
virtual const uniset::ObjectInfo* getObjectInfo( const std::string& name ) const noexcept override;
virtual uniset::ObjectId getIdByName( const std::string& name ) const noexcept override;
virtual std::string getMapName( const uniset::ObjectId id ) const noexcept override;
virtual std::string getTextName( const uniset::ObjectId id ) const noexcept override;
virtual std::ostream& printMap( std::ostream& os ) const noexcept override;
friend std::ostream& operator<<(std::ostream& os, ObjectIndex_hashXML& oi );
protected:
void build( const std::shared_ptr<UniXML>& xml );
void read_section( const std::shared_ptr<UniXML>& xml, const std::string& sec );
void read_nodes( const std::shared_ptr<UniXML>& xml, const std::string& sec );
private:
typedef std::unordered_map<uniset::ObjectId, uniset::ObjectInfo> MapObjects;
MapObjects omap;
typedef std::unordered_map<std::string, uniset::ObjectId> MapObjectKey;
MapObjectKey mok; // для обратного писка
};
// -------------------------------------------------------------------------
} // end of uniset namespace
// -----------------------------------------------------------------------------------------
#endif
......@@ -82,6 +82,11 @@ namespace uniset
KeyType key( const uniset::ObjectId id, const uniset::ObjectId node );
KeyType key( const IOController_i::SensorInfo& si );
uint64_t hash64( const std::string& str ) noexcept;
uint64_t hash64( const char* buf, size_t sz ) noexcept;
uint32_t hash32( const std::string& str ) noexcept;
uint32_t hash32( const char* buf, size_t sz ) noexcept;
typedef std::list<std::string> ListObjectName; /*!< Список объектов типа ObjectName */
typedef CORBA::Object_ptr ObjectPtr; /*!< Ссылка на объект, регистрируемый в ObjectRepository */
......
......@@ -34,8 +34,8 @@
#include "Exceptions.h"
#include "MessageType.h"
#include "ObjectIndex_Array.h"
#include "ObjectIndex_XML.h"
#include "ObjectIndex_idXML.h"
#include "ObjectIndex_hashXML.h"
#include "UniSetActivator.h"
// -------------------------------------------------------------------------
using namespace std;
......@@ -1538,6 +1538,4 @@ namespace uniset
return uniset::uconf;
}
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
} // end of UniSetTypes namespace
noinst_LTLIBRARIES = libUCore.la
libUCore_la_LIBADD = $(top_builddir)/contrib/cityhash102/libCityHash102.la $(top_builddir)/contrib/libfarmhash/libFarmHash.la
libUCore_la_CPPFLAGS = -I$(top_builddir)/contrib/cityhash102/include -I$(top_builddir)/contrib/libfarmhash
libUCore_la_SOURCES = UniSetTypes_iSK.cc UniSetObject_iSK.cc UniSetTypes.cc \
UniSetManager_iSK.cc UniSetObject.cc UniSetManager.cc UniSetActivator.cc \
Configuration.cc MessageType.cc UInterface.cc
......
......@@ -25,6 +25,8 @@
#include <Poco/File.h>
#include "UniSetTypes.h"
#include "Configuration.h"
#include "city.h"
#include "farmhash.h"
// -----------------------------------------------------------------------------
using namespace std;
using namespace uniset;
......@@ -741,3 +743,22 @@ uniset::KeyType uniset::key( const IOController_i::SensorInfo& si )
return key(si.id, si.node);
}
// ---------------------------------------------------------------------------------------------------------------
uint64_t uniset::hash64( const std::string& str ) noexcept
{
return CityHash_v1_0_2::CityHash64(str.data(), str.size());
}
uint64_t uniset::hash64( const char* buf, size_t sz ) noexcept
{
return CityHash_v1_0_2::CityHash64(buf, sz);
}
// ---------------------------------------------------------------------------------------------------------------
uint32_t uniset::hash32( const std::string& str ) noexcept
{
return NAMESPACE_FOR_HASH_FUNCTIONS::Hash32(str.data(), str.size());
}
uint32_t uniset::hash32( const char* buf, size_t sz ) noexcept
{
return NAMESPACE_FOR_HASH_FUNCTIONS::Hash32(buf, sz);
}
noinst_LTLIBRARIES = libObjectsRepository.la
libObjectsRepository_la_SOURCES = ObjectIndex.cc ObjectIndex_Array.cc ObjectIndex_XML.cc ObjectIndex_idXML.cc \
ORepHelpers.cc ObjectRepository.cc IORFile.cc
ORepHelpers.cc ObjectRepository.cc IORFile.cc ObjectIndex_hashXML.cc
# ServiceActivator.cc
include $(top_builddir)/include.mk
......@@ -24,9 +24,10 @@
#include "Configuration.h"
// -----------------------------------------------------------------------------------------
using namespace uniset;
using namespace std;
// -----------------------------------------------------------------------------------------
namespace uniset {
// -----------------------------------------------------------------------------------------
ObjectIndex_Array::~ObjectIndex_Array()
{
......@@ -119,3 +120,5 @@ const ObjectInfo* ObjectIndex_Array::getObjectInfo( const std::string& name ) co
return NULL;
}
// ------------------------------------------------------------------------------------------
} // end of namespace uniset
// ------------------------------------------------------------------------------------------
......@@ -21,9 +21,10 @@
#include "Configuration.h"
// -----------------------------------------------------------------------------------------
using namespace uniset;
using namespace std;
// -----------------------------------------------------------------------------------------
namespace uniset {
// -----------------------------------------------------------------------------------------
ObjectIndex_XML::ObjectIndex_XML(const string& xmlfile, size_t minSize )
{
omap.reserve(minSize);
......@@ -299,3 +300,5 @@ const ObjectInfo* ObjectIndex_XML::getObjectInfo( const std::string& name ) cons
return nullptr;
}
// ------------------------------------------------------------------------------------------
} // end of namespace uniset
// ------------------------------------------------------------------------------------------
/*
* Copyright (c) 2020 Pavel Vainerman.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, version 2.1.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Lesser Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// -----------------------------------------------------------------------------------------
#include <sstream>
#include <iomanip>
#include "ORepHelpers.h"
#include "Configuration.h"
#include "ObjectIndex_hashXML.h"
#include "UniSetTypes.h"
// -----------------------------------------------------------------------------------------
using namespace std;
// -----------------------------------------------------------------------------------------
namespace uniset
{
// -----------------------------------------------------------------------------------------
ObjectIndex_hashXML::ObjectIndex_hashXML( const string& xmlfile )
{
auto xml = make_shared<UniXML>();
// try
// {
xml->open(xmlfile);
build(xml);
// }
// catch(...){}
}
// -----------------------------------------------------------------------------------------
ObjectIndex_hashXML::ObjectIndex_hashXML( const shared_ptr<UniXML>& xml )
{
build(xml);
}
// -----------------------------------------------------------------------------------------
ObjectIndex_hashXML::~ObjectIndex_hashXML()
{
}
// -----------------------------------------------------------------------------------------
ObjectId ObjectIndex_hashXML::getIdByName( const string& name ) const noexcept
{
try
{
auto it = mok.find(name);
if( it != mok.end() )
return it->second;
}
catch(...) {}
return DefaultObjectId;
}
// -----------------------------------------------------------------------------------------
string ObjectIndex_hashXML::getMapName( const ObjectId id ) const noexcept
{
try
{
auto it = omap.find(id);
if( it != omap.end() )
return it->second.repName;
}
catch(...) {}
return "";
}
// -----------------------------------------------------------------------------------------
string ObjectIndex_hashXML::getTextName( const ObjectId id ) const noexcept
{
try
{
auto it = omap.find(id);
if( it != omap.end() )
return it->second.textName;
}
catch(...) {}
return "";
}
// -----------------------------------------------------------------------------------------
std::ostream& operator<<(std::ostream& os, ObjectIndex_hashXML& oi )
{
return oi.printMap(os);
}
// -----------------------------------------------------------------------------------------
std::ostream& ObjectIndex_hashXML::printMap( std::ostream& os ) const noexcept
{
os << "size: " << omap.size() << endl;
for( auto it = omap.begin(); it != omap.end(); ++it )
{
if( it->second.repName.empty() )
continue;
os << setw(5) << it->second.id << " "
// << setw(45) << ORepHelpers::getShortName(it->repName,'/')
<< setw(45) << it->second.repName
<< " " << it->second.textName << endl;
}
return os;
}
// -----------------------------------------------------------------------------------------
void ObjectIndex_hashXML::build( const shared_ptr<UniXML>& xml )
{
read_section(xml, "sensors");
read_section(xml, "objects");
read_section(xml, "controllers");
read_section(xml, "services");
read_nodes(xml, "nodes");
}
// ------------------------------------------------------------------------------------------
void ObjectIndex_hashXML::read_section( const std::shared_ptr<UniXML>& xml, const std::string& sec )
{
string secRoot = xml->getProp( xml->findNode(xml->getFirstNode(), "RootSection"), "name");
if( secRoot.empty() )
{
ostringstream msg;
msg << "(ObjectIndex_hashXML::build):: не нашли параметр RootSection в конф. файле ";
ucrit << msg.str() << endl;
throw SystemError(msg.str());
}
xmlNode* root( xml->findNode(xml->getFirstNode(), sec) );
if( !root )
{
ostringstream msg;
msg << "(ObjectIndex_hashXML::build): не нашли корневого раздела " << sec;
throw NameNotFound(msg.str());
}
// Считываем список элементов
UniXML::iterator it(root);
if( !it.goChildren() )
{
ostringstream msg;
msg << "(ObjectIndex_hashXML::build): не удалось перейти к списку элементов " << sec;
throw NameNotFound(msg.str());
}
string secname = xml->getProp(root, "section");
if( secname.empty() )
secname = xml->getProp(root, "name");
if( secname.empty() )
{
ostringstream msg;
msg << "(ObjectIndex_hashXML::build): у секции " << sec << " не указано свойство 'name' ";
throw NameNotFound(msg.str());
}
// прибавим корень
secname = secRoot + "/" + secname + "/";
for( ; it.getCurrent(); it.goNext() )
{
if( !it.getProp("id").empty() )
{
ostringstream err;
err << "(ObjectIndex_hashXML): ERROR in " << xml->getFileName() << " format: Don`t use id='xxx' or use flag 'idfromfile' in <ObjectsMap idfromfile='1'>";
throw uniset::SystemError(err.str());
}
ObjectInfo inf;
const std::string nm = it.getProp("name");
if( nm.empty() )
{
ostringstream err;
err << "Unknown name fot item (section '" << secname << "'). User name='xxx'";
throw uniset::SystemError(err.str());
}
inf.id = uniset::hash32(nm);
// name
ostringstream n;
n << secname << nm;
const string name(n.str());
inf.repName = name;
string textname(xml->getProp(it, "textname"));
if( textname.empty() )
textname = nm;
inf.textName = textname;
inf.xmlnode = it;
auto mret = mok.emplace(name, inf.id);
if( !mret.second )
{
ostringstream err;
err << "Object name collision. The '" << nm << "' already exists.";
throw uniset::SystemError(err.str());
}
auto ret = omap.emplace(inf.id, std::move(inf));
if( !ret.second )
{
ostringstream err;
err << "ObjectID collision. The '" << nm << "' already exists.";
throw uniset::SystemError(err.str());
}
}
}
// ------------------------------------------------------------------------------------------
void ObjectIndex_hashXML::read_nodes( const std::shared_ptr<UniXML>& xml, const std::string& sec )
{
xmlNode* root( xml->findNode(xml->getFirstNode(), sec) );
if( !root )
{
ostringstream msg;
msg << "(ObjectIndex_hashXML::build): не нашли корневого раздела " << sec;
throw NameNotFound(msg.str());
}
// Считываем список элементов
UniXML::iterator it(root);
if( !it.goChildren() )
{
ostringstream msg;
msg << "(ObjectIndex_hashXML::build): не удалось перейти к списку элементов "
<< " секция " << sec;
throw NameNotFound(msg.str());
}
for( ; it.getCurrent(); it.goNext() )
{
ObjectInfo inf;
if( !it.getProp("id").empty() )
{
ostringstream err;
err << "(ObjectIndex_hashXML): ERROR in " << xml->getFileName() << " format: Don`t use id='xxx' or use flag 'idfromfile' in <ObjectsMap idfromfile='1'>";
throw uniset::SystemError(err.str());
}
const string name(it.getProp("name"));
inf.id = uniset::hash32(name);
inf.repName = name;
// textname
string textname(xml->getProp(it, "textname"));
if( textname.empty() )
textname = name;
inf.textName = textname;
inf.xmlnode = it;
auto ret = omap.emplace(inf.id, inf);
if( !ret.second )
{
ostringstream err;
err << "node ObjectID collision. The '" << name << "' already exists.";
throw uniset::SystemError(err.str());
}
auto mret = mok.emplace(name, inf.id);
if( !mret.second )
{
ostringstream err;
err << "Node name collision. The '" << name << "' already exists.";
throw uniset::SystemError(err.str());
}
}
}
// ------------------------------------------------------------------------------------------
const ObjectInfo* ObjectIndex_hashXML::getObjectInfo( const ObjectId id ) const noexcept
{
try
{
auto it = omap.find(id);
if( it != omap.end() )
return &(it->second);
}
catch(...) {}
return nullptr;
}
// ------------------------------------------------------------------------------------------
const ObjectInfo* ObjectIndex_hashXML::getObjectInfo( const std::string& name ) const noexcept
{
try
{
auto it = mok.find(name);
if( it != mok.end() )
return getObjectInfo(it->second);
}
catch(...) {}
return nullptr;
}
// ------------------------------------------------------------------------------------------
} // end of namespace uniset
// ------------------------------------------------------------------------------------------
......@@ -20,9 +20,10 @@
#include "Configuration.h"
#include "ObjectIndex_idXML.h"
// -----------------------------------------------------------------------------------------
using namespace uniset;
using namespace std;
// -----------------------------------------------------------------------------------------
namespace uniset {
// -----------------------------------------------------------------------------------------
ObjectIndex_idXML::ObjectIndex_idXML( const string& xmlfile )
{
auto xml = make_shared<UniXML>();
......@@ -275,3 +276,5 @@ const ObjectInfo* ObjectIndex_idXML::getObjectInfo( const std::string& name ) co
return nullptr;
}
// ------------------------------------------------------------------------------------------
} // end of namespace uniset
// ------------------------------------------------------------------------------------------
......@@ -29,12 +29,13 @@ test_logserver.cc \
test_tcpcheck.cc \
test_utcpsocket.cc \
test_iocontroller_types.cc \
test_debugstream.cc
test_debugstream.cc \
test_oindex_hash.cc
#test_uhttp.cc
tests_with_conf_LDADD = $(top_builddir)/lib/libUniSet2.la
tests_with_conf_CPPFLAGS = -I$(top_builddir)/include
tests_with_conf_LDADD = $(top_builddir)/lib/libUniSet2.la $(top_builddir)/contrib/cityhash102/libCityHash102.la $(top_builddir)/contrib/libfarmhash/libFarmHash.la
tests_with_conf_CPPFLAGS = -I$(top_builddir)/include -I$(top_builddir)/contrib/cityhash102/include -I$(top_builddir)/contrib/libfarmhash
tests_with_conf_SOURCES = tests_with_conf.cc \
test_conftest.cc \
test_ui.cc \
......
#include <catch.hpp>
// -----------------------------------------------------------------------------
#include <iostream>
#include <sstream>
// -----------------------------------------------------------------------------
#include "Exceptions.h"
#include "ObjectIndex_hashXML.h"
#include "UniSetTypes.h"
// -----------------------------------------------------------------------------
using namespace std;
using namespace uniset;
// -----------------------------------------------------------------------------
TEST_CASE("ObjectIndexHash", "[oindex_hash][basic]" )
{
ObjectIndex_hashXML oi("tests_oindex_hash_config.xml");
REQUIRE( oi.getIdByName("UNISET_PLC/Sensors/Input1_S") == uniset::hash32("Input1_S") );
REQUIRE( oi.getIdByName("UNISET_PLC/Sensors/Input2_S") == uniset::hash32("Input2_S") );
}
// -----------------------------------------------------------------------------
TEST_CASE("ObjectIndexHash: collision", "[oindex_hash][base][collision]" )
{
REQUIRE_THROWS_AS( ObjectIndex_hashXML("tests_oindex_hash_collision_config.xml"), uniset::SystemError& );
}
......@@ -406,3 +406,18 @@ TEST_CASE("UniSetTypes: ios_fmt_restorer", "[utypes][ios_fmt_restorer]" )
REQUIRE( s.str() == " 5" );
}
// -----------------------------------------------------------------------------
TEST_CASE("UniSetTypes: hash64", "[utypes][hash64]" )
{
REQUIRE( uniset::hash64("test") == uint64_t(17703940110308125106) );
REQUIRE( uniset::hash64("test2") == uint64_t(11165864767333097451) );
REQUIRE( uniset::hash64("2tset") == uint64_t(15246161741804761271) );
}
// -----------------------------------------------------------------------------
TEST_CASE("UniSetTypes: hash32", "[utypes][hash32]" )
{
REQUIRE( sizeof(uniset::ObjectId) == sizeof(uint32_t) );
REQUIRE( uniset::hash32("test") == uint32_t(168770635) );
REQUIRE( uniset::hash32("test2") == uint32_t(4018550908) );
REQUIRE( uniset::hash32("2tset") == uint32_t(1660083104) );
}
// -----------------------------------------------------------------------------
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment