mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 19:23:03 +01:00
Refactor introducing HashContext and WeakHashContext.
This commit is contained in:
parent
8c5c9bdc61
commit
7fe1fbbae3
@ -108,3 +108,26 @@ unsigned int InternalHash::hash(unsigned int length, const UCHAR* value)
|
||||
{
|
||||
return internalHash(length, value);
|
||||
}
|
||||
|
||||
|
||||
void WeakHashContext::update(const void* data, FB_SIZE_T length)
|
||||
{
|
||||
const UCHAR* p = static_cast<const UCHAR*>(data);
|
||||
|
||||
for (const UCHAR* end = p + length; p != end; ++p)
|
||||
{
|
||||
hashNumber = (hashNumber << 4) + *p;
|
||||
|
||||
const SINT64 n = hashNumber & FB_CONST64(0xF000000000000000);
|
||||
if (n)
|
||||
hashNumber ^= n >> 56;
|
||||
|
||||
hashNumber &= ~n;
|
||||
}
|
||||
}
|
||||
|
||||
void WeakHashContext::finish(Buffer& result)
|
||||
{
|
||||
UCHAR* resultBuffer = result.getBuffer(sizeof(hashNumber));
|
||||
memcpy(resultBuffer, &hashNumber, sizeof(hashNumber));
|
||||
}
|
||||
|
@ -28,7 +28,7 @@
|
||||
#ifndef CLASSES_HASH_H
|
||||
#define CLASSES_HASH_H
|
||||
|
||||
#include "../common/classes/vector.h"
|
||||
#include "../common/classes/array.h"
|
||||
|
||||
namespace Firebird
|
||||
{
|
||||
@ -341,7 +341,31 @@ namespace Firebird
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class HashContext
|
||||
{
|
||||
public:
|
||||
typedef HalfStaticArray<UCHAR, 256> Buffer;
|
||||
|
||||
public:
|
||||
virtual ~HashContext()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void update(const void* data, FB_SIZE_T length) = 0;
|
||||
virtual void finish(Buffer& result) = 0;
|
||||
};
|
||||
|
||||
class WeakHashContext FB_FINAL : public HashContext
|
||||
{
|
||||
public:
|
||||
virtual void update(const void* data, FB_SIZE_T length);
|
||||
virtual void finish(Buffer& result);
|
||||
|
||||
private:
|
||||
SINT64 hashNumber = 0;
|
||||
};
|
||||
} // namespace Firebird
|
||||
|
||||
#endif // CLASSES_HASH_H
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include "firebird.h"
|
||||
#include "../common/classes/VaryStr.h"
|
||||
#include "../common/classes/Hash.h"
|
||||
#include "../jrd/SysFunction.h"
|
||||
#include "../jrd/DataTypeUtil.h"
|
||||
#include "../include/fb_blk.h"
|
||||
@ -2647,10 +2648,9 @@ dsc* evlHash(thread_db* tdbb, const SysFunction*, const NestValueArray& args,
|
||||
if (request->req_flags & req_null) // return NULL if value is NULL
|
||||
return NULL;
|
||||
|
||||
WeakHashContext hashContext;
|
||||
impure->vlu_misc.vlu_int64 = 0;
|
||||
|
||||
UCHAR* address;
|
||||
|
||||
if (value->isBlob())
|
||||
{
|
||||
UCHAR buffer[BUFFER_LARGE];
|
||||
@ -2659,38 +2659,26 @@ dsc* evlHash(thread_db* tdbb, const SysFunction*, const NestValueArray& args,
|
||||
|
||||
while (!(blob->blb_flags & BLB_eof))
|
||||
{
|
||||
address = buffer;
|
||||
const ULONG length = blob->BLB_get_data(tdbb, address, sizeof(buffer), false);
|
||||
|
||||
for (const UCHAR* end = address + length; address < end; ++address)
|
||||
{
|
||||
impure->vlu_misc.vlu_int64 = (impure->vlu_misc.vlu_int64 << 4) + *address;
|
||||
|
||||
const SINT64 n = impure->vlu_misc.vlu_int64 & FB_CONST64(0xF000000000000000);
|
||||
if (n)
|
||||
impure->vlu_misc.vlu_int64 ^= n >> 56;
|
||||
impure->vlu_misc.vlu_int64 &= ~n;
|
||||
}
|
||||
const ULONG length = blob->BLB_get_data(tdbb, buffer, sizeof(buffer), false);
|
||||
hashContext.update(buffer, length);
|
||||
}
|
||||
|
||||
blob->BLB_close(tdbb);
|
||||
}
|
||||
else
|
||||
{
|
||||
UCHAR* address;
|
||||
MoveBuffer buffer;
|
||||
const ULONG length = MOV_make_string2(tdbb, value, value->getTextType(), &address, buffer, false);
|
||||
|
||||
for (const UCHAR* end = address + length; address < end; ++address)
|
||||
{
|
||||
impure->vlu_misc.vlu_int64 = (impure->vlu_misc.vlu_int64 << 4) + *address;
|
||||
|
||||
const SINT64 n = impure->vlu_misc.vlu_int64 & FB_CONST64(0xF000000000000000);
|
||||
if (n)
|
||||
impure->vlu_misc.vlu_int64 ^= n >> 56;
|
||||
impure->vlu_misc.vlu_int64 &= ~n;
|
||||
}
|
||||
hashContext.update(address, length);
|
||||
}
|
||||
|
||||
HashContext::Buffer resultBuffer;
|
||||
hashContext.finish(resultBuffer);
|
||||
|
||||
fb_assert(resultBuffer.getCount() == sizeof(SINT64));
|
||||
memcpy(&impure->vlu_misc.vlu_int64, resultBuffer.begin(), sizeof(SINT64));
|
||||
|
||||
// make descriptor for return value
|
||||
impure->vlu_desc.makeInt64(0, &impure->vlu_misc.vlu_int64);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user