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 @@ ...@@ -3,7 +3,7 @@
############################################################################ ############################################################################
FIRSTSUBDIRS=IDL FIRSTSUBDIRS=IDL
SUBDIRS=. src lib include Utilities tests extensions wrappers docs SUBDIRS=. contrib src lib include Utilities tests extensions wrappers docs
# testsuite # testsuite
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig
......
...@@ -274,7 +274,6 @@ fi ...@@ -274,7 +274,6 @@ fi
AM_CONDITIONAL(HAVE_EXTENTIONS, test ${ext} = true) AM_CONDITIONAL(HAVE_EXTENTIONS, test ${ext} = true)
#check python support #check python support
AC_MSG_CHECKING([python support]) AC_MSG_CHECKING([python support])
buildpython=true buildpython=true
...@@ -376,7 +375,7 @@ fi ...@@ -376,7 +375,7 @@ fi
AC_MSG_CHECKING([catch version in $CATCH_FILE]) AC_MSG_CHECKING([catch version in $CATCH_FILE])
CATCH_RESULT= CATCH_RESULT=
if cat ${CATCH_FILE} | grep -q "Catch v2."; then if cat ${CATCH_FILE} | grep -q "Catch v2."; then
CATCH_VERSION_MAJOR=2; CATCH_VERSION_MAJOR=2;
fi fi
AC_MSG_RESULT([$CATCH_VERSION_MAJOR]) AC_MSG_RESULT([$CATCH_VERSION_MAJOR])
...@@ -531,6 +530,9 @@ AC_CONFIG_FILES([Makefile ...@@ -531,6 +530,9 @@ AC_CONFIG_FILES([Makefile
IDL/UniSetTypes/Makefile IDL/UniSetTypes/Makefile
IDL/UniSetTypes/UniSetBaseConstants.idl IDL/UniSetTypes/UniSetBaseConstants.idl
IDL/Processes/Makefile IDL/Processes/Makefile
contrib/Makefile
contrib/cityhash102/Makefile
contrib/libfarmhash/Makefile
src/Core/Makefile src/Core/Makefile
src/Communications/Makefile src/Communications/Makefile
src/Communications/Modbus/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 ( CREATE TABLE main_history (
id PRIMARY KEY NOT NULL, id BIGSERIAL PRIMARY KEY NOT NULL,
date date NOT NULL, date date NOT NULL,
time time NOT NULL, time time NOT NULL,
time_usec int NOT NULL CHECK (time_usec >= 0), time_usec int NOT NULL CHECK (time_usec >= 0),
sensor_id int NOT NULL, sensor_id int NOT NULL,
value double precision NOT NULL, value double precision NOT NULL,
node int NOT NULL, node int NOT NULL,
confirm int DEFAULT NULL, confirm int DEFAULT NULL
PRIMARY KEY (id)
); );
...@@ -32,6 +32,7 @@ namespace uniset ...@@ -32,6 +32,7 @@ namespace uniset
{ {
/*! реализация интерфейса ObjectIndex на основе xml-файла, с автоматическим назначением id объектам /*! реализация интерфейса ObjectIndex на основе xml-файла, с автоматическим назначением id объектам
* DEPRECATED! Use ObjectIndex_hashXML!
* *
* \todo Проверить функции этого класса на повторную входимость * \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 ...@@ -82,6 +82,11 @@ namespace uniset
KeyType key( const uniset::ObjectId id, const uniset::ObjectId node ); KeyType key( const uniset::ObjectId id, const uniset::ObjectId node );
KeyType key( const IOController_i::SensorInfo& si ); 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 std::list<std::string> ListObjectName; /*!< Список объектов типа ObjectName */
typedef CORBA::Object_ptr ObjectPtr; /*!< Ссылка на объект, регистрируемый в ObjectRepository */ typedef CORBA::Object_ptr ObjectPtr; /*!< Ссылка на объект, регистрируемый в ObjectRepository */
......
...@@ -34,8 +34,8 @@ ...@@ -34,8 +34,8 @@
#include "Exceptions.h" #include "Exceptions.h"
#include "MessageType.h" #include "MessageType.h"
#include "ObjectIndex_Array.h" #include "ObjectIndex_Array.h"
#include "ObjectIndex_XML.h"
#include "ObjectIndex_idXML.h" #include "ObjectIndex_idXML.h"
#include "ObjectIndex_hashXML.h"
#include "UniSetActivator.h" #include "UniSetActivator.h"
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
using namespace std; using namespace std;
...@@ -1538,6 +1538,4 @@ namespace uniset ...@@ -1538,6 +1538,4 @@ namespace uniset
return uniset::uconf; return uniset::uconf;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// -------------------------------------------------------------------------
} // end of UniSetTypes namespace } // end of UniSetTypes namespace
noinst_LTLIBRARIES = libUCore.la 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 \ libUCore_la_SOURCES = UniSetTypes_iSK.cc UniSetObject_iSK.cc UniSetTypes.cc \
UniSetManager_iSK.cc UniSetObject.cc UniSetManager.cc UniSetActivator.cc \ UniSetManager_iSK.cc UniSetObject.cc UniSetManager.cc UniSetActivator.cc \
Configuration.cc MessageType.cc UInterface.cc Configuration.cc MessageType.cc UInterface.cc
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#include <Poco/File.h> #include <Poco/File.h>
#include "UniSetTypes.h" #include "UniSetTypes.h"
#include "Configuration.h" #include "Configuration.h"
#include "city.h"
#include "farmhash.h"
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
using namespace std; using namespace std;
using namespace uniset; using namespace uniset;
...@@ -741,3 +743,22 @@ uniset::KeyType uniset::key( const IOController_i::SensorInfo& si ) ...@@ -741,3 +743,22 @@ uniset::KeyType uniset::key( const IOController_i::SensorInfo& si )
return key(si.id, si.node); 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 noinst_LTLIBRARIES = libObjectsRepository.la
libObjectsRepository_la_SOURCES = ObjectIndex.cc ObjectIndex_Array.cc ObjectIndex_XML.cc ObjectIndex_idXML.cc \ 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 # ServiceActivator.cc
include $(top_builddir)/include.mk include $(top_builddir)/include.mk
...@@ -24,9 +24,10 @@ ...@@ -24,9 +24,10 @@
#include "Configuration.h" #include "Configuration.h"
// ----------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------
using namespace uniset;
using namespace std; using namespace std;
// ----------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------
namespace uniset {
// -----------------------------------------------------------------------------------------
ObjectIndex_Array::~ObjectIndex_Array() ObjectIndex_Array::~ObjectIndex_Array()
{ {
...@@ -119,3 +120,5 @@ const ObjectInfo* ObjectIndex_Array::getObjectInfo( const std::string& name ) co ...@@ -119,3 +120,5 @@ const ObjectInfo* ObjectIndex_Array::getObjectInfo( const std::string& name ) co
return NULL; return NULL;
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
} // end of namespace uniset
// ------------------------------------------------------------------------------------------
...@@ -21,9 +21,10 @@ ...@@ -21,9 +21,10 @@
#include "Configuration.h" #include "Configuration.h"
// ----------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------
using namespace uniset;
using namespace std; using namespace std;
// ----------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------
namespace uniset {
// -----------------------------------------------------------------------------------------
ObjectIndex_XML::ObjectIndex_XML(const string& xmlfile, size_t minSize ) ObjectIndex_XML::ObjectIndex_XML(const string& xmlfile, size_t minSize )
{ {
omap.reserve(minSize); omap.reserve(minSize);
...@@ -299,3 +300,5 @@ const ObjectInfo* ObjectIndex_XML::getObjectInfo( const std::string& name ) cons ...@@ -299,3 +300,5 @@ const ObjectInfo* ObjectIndex_XML::getObjectInfo( const std::string& name ) cons
return nullptr; 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 @@ ...@@ -20,9 +20,10 @@
#include "Configuration.h" #include "Configuration.h"
#include "ObjectIndex_idXML.h" #include "ObjectIndex_idXML.h"
// ----------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------
using namespace uniset;
using namespace std; using namespace std;
// ----------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------
namespace uniset {
// -----------------------------------------------------------------------------------------
ObjectIndex_idXML::ObjectIndex_idXML( const string& xmlfile ) ObjectIndex_idXML::ObjectIndex_idXML( const string& xmlfile )
{ {
auto xml = make_shared<UniXML>(); auto xml = make_shared<UniXML>();
...@@ -275,3 +276,5 @@ const ObjectInfo* ObjectIndex_idXML::getObjectInfo( const std::string& name ) co ...@@ -275,3 +276,5 @@ const ObjectInfo* ObjectIndex_idXML::getObjectInfo( const std::string& name ) co
return nullptr; return nullptr;
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
} // end of namespace uniset
// ------------------------------------------------------------------------------------------
...@@ -29,12 +29,13 @@ test_logserver.cc \ ...@@ -29,12 +29,13 @@ test_logserver.cc \
test_tcpcheck.cc \ test_tcpcheck.cc \
test_utcpsocket.cc \ test_utcpsocket.cc \
test_iocontroller_types.cc \ test_iocontroller_types.cc \
test_debugstream.cc test_debugstream.cc \
test_oindex_hash.cc
#test_uhttp.cc #test_uhttp.cc
tests_with_conf_LDADD = $(top_builddir)/lib/libUniSet2.la 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 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 \ tests_with_conf_SOURCES = tests_with_conf.cc \
test_conftest.cc \ test_conftest.cc \
test_ui.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]" ) ...@@ -406,3 +406,18 @@ TEST_CASE("UniSetTypes: ios_fmt_restorer", "[utypes][ios_fmt_restorer]" )
REQUIRE( s.str() == " 5" ); 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