mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
tux optim 14 - use pointers to cmp functions
ndb/test/ndbapi/testOIBasic.cpp: null related options, not related to this changeset
This commit is contained in:
@ -40,8 +40,9 @@ public:
|
||||
* Compare kernel attribute values. Returns -1, 0, +1 for less,
|
||||
* equal, greater, respectively. Parameters are pointers to values,
|
||||
* full attribute size in words, and size of available data in words.
|
||||
* There are 2 special return values to check first. All values fit
|
||||
* into a signed char.
|
||||
* If available size is less than full size, CmpUnknown may be
|
||||
* returned. If a value cannot be parsed, it compares like NULL i.e.
|
||||
* less than any valid value.
|
||||
*/
|
||||
typedef int Cmp(const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size);
|
||||
|
||||
@ -49,8 +50,7 @@ public:
|
||||
CmpLess = -1,
|
||||
CmpEqual = 0,
|
||||
CmpGreater = 1,
|
||||
CmpUnknown = 126, // insufficient partial data
|
||||
CmpError = 127 // bad data format or unimplemented comparison
|
||||
CmpUnknown = 2 // insufficient partial data
|
||||
};
|
||||
|
||||
/**
|
||||
@ -82,19 +82,13 @@ public:
|
||||
Text // Text blob
|
||||
};
|
||||
Enum m_typeId;
|
||||
Cmp* m_cmp; // set to NULL if cmp not implemented
|
||||
Cmp* m_cmp; // comparison method
|
||||
};
|
||||
|
||||
/**
|
||||
* Get type by id. Can return the Undefined type.
|
||||
*/
|
||||
static const Type& type(Uint32 typeId);
|
||||
|
||||
/**
|
||||
* Inline comparison method. Most or all real methods Type::m_cmp are
|
||||
* implemented via this (trusting dead code elimination).
|
||||
*/
|
||||
static int cmp(Uint32 typeId, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size);
|
||||
static const Type& getType(Uint32 typeId);
|
||||
|
||||
private:
|
||||
/**
|
||||
@ -127,323 +121,4 @@ private:
|
||||
static Cmp cmpText;
|
||||
};
|
||||
|
||||
inline int
|
||||
NdbSqlUtil::cmp(Uint32 typeId, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size)
|
||||
{
|
||||
// XXX require size >= 1
|
||||
if (size > full)
|
||||
return CmpError;
|
||||
switch ((Type::Enum)typeId) {
|
||||
case Type::Undefined:
|
||||
break;
|
||||
case Type::Tinyint:
|
||||
{
|
||||
if (size >= 1) {
|
||||
union { Uint32 p[1]; Int8 v; } u1, u2;
|
||||
u1.p[0] = p1[0];
|
||||
u2.p[0] = p2[0];
|
||||
if (u1.v < u2.v)
|
||||
return -1;
|
||||
if (u1.v > u2.v)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
return CmpUnknown;
|
||||
}
|
||||
case Type::Tinyunsigned:
|
||||
{
|
||||
if (size >= 1) {
|
||||
union { Uint32 p[1]; Uint8 v; } u1, u2;
|
||||
u1.p[0] = p1[0];
|
||||
u2.p[0] = p2[0];
|
||||
if (u1.v < u2.v)
|
||||
return -1;
|
||||
if (u1.v > u2.v)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
return CmpUnknown;
|
||||
}
|
||||
case Type::Smallint:
|
||||
{
|
||||
if (size >= 1) {
|
||||
union { Uint32 p[1]; Int16 v; } u1, u2;
|
||||
u1.p[0] = p1[0];
|
||||
u2.p[0] = p2[0];
|
||||
if (u1.v < u2.v)
|
||||
return -1;
|
||||
if (u1.v > u2.v)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
return CmpUnknown;
|
||||
}
|
||||
case Type::Smallunsigned:
|
||||
{
|
||||
if (size >= 1) {
|
||||
union { Uint32 p[1]; Uint16 v; } u1, u2;
|
||||
u1.p[0] = p1[0];
|
||||
u2.p[0] = p2[0];
|
||||
if (u1.v < u2.v)
|
||||
return -1;
|
||||
if (u1.v > u2.v)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
return CmpUnknown;
|
||||
}
|
||||
case Type::Mediumint:
|
||||
{
|
||||
if (size >= 1) {
|
||||
union { const Uint32* p; const unsigned char* v; } u1, u2;
|
||||
u1.p = p1;
|
||||
u2.p = p2;
|
||||
Int32 v1 = sint3korr(u1.v);
|
||||
Int32 v2 = sint3korr(u2.v);
|
||||
if (v1 < v2)
|
||||
return -1;
|
||||
if (v1 > v2)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
return CmpUnknown;
|
||||
}
|
||||
case Type::Mediumunsigned:
|
||||
{
|
||||
if (size >= 1) {
|
||||
union { const Uint32* p; const unsigned char* v; } u1, u2;
|
||||
u1.p = p1;
|
||||
u2.p = p2;
|
||||
Uint32 v1 = uint3korr(u1.v);
|
||||
Uint32 v2 = uint3korr(u2.v);
|
||||
if (v1 < v2)
|
||||
return -1;
|
||||
if (v1 > v2)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
return CmpUnknown;
|
||||
}
|
||||
case Type::Int:
|
||||
{
|
||||
if (size >= 1) {
|
||||
union { Uint32 p[1]; Int32 v; } u1, u2;
|
||||
u1.p[0] = p1[0];
|
||||
u2.p[0] = p2[0];
|
||||
if (u1.v < u2.v)
|
||||
return -1;
|
||||
if (u1.v > u2.v)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
return CmpUnknown;
|
||||
}
|
||||
case Type::Unsigned:
|
||||
{
|
||||
if (size >= 1) {
|
||||
union { Uint32 p[1]; Uint32 v; } u1, u2;
|
||||
u1.v = p1[0];
|
||||
u2.v = p2[0];
|
||||
if (u1.v < u2.v)
|
||||
return -1;
|
||||
if (u1.v > u2.v)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
return CmpUnknown;
|
||||
}
|
||||
case Type::Bigint:
|
||||
{
|
||||
if (size >= 2) {
|
||||
union { Uint32 p[2]; Int64 v; } u1, u2;
|
||||
u1.p[0] = p1[0];
|
||||
u1.p[1] = p1[1];
|
||||
u2.p[0] = p2[0];
|
||||
u2.p[1] = p2[1];
|
||||
if (u1.v < u2.v)
|
||||
return -1;
|
||||
if (u1.v > u2.v)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
return CmpUnknown;
|
||||
}
|
||||
case Type::Bigunsigned:
|
||||
{
|
||||
if (size >= 2) {
|
||||
union { Uint32 p[2]; Uint64 v; } u1, u2;
|
||||
u1.p[0] = p1[0];
|
||||
u1.p[1] = p1[1];
|
||||
u2.p[0] = p2[0];
|
||||
u2.p[1] = p2[1];
|
||||
if (u1.v < u2.v)
|
||||
return -1;
|
||||
if (u1.v > u2.v)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
return CmpUnknown;
|
||||
}
|
||||
case Type::Float:
|
||||
{
|
||||
if (size >= 1) {
|
||||
union { Uint32 p[1]; float v; } u1, u2;
|
||||
u1.p[0] = p1[0];
|
||||
u2.p[0] = p2[0];
|
||||
if (u1.v < u2.v)
|
||||
return -1;
|
||||
if (u1.v > u2.v)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
return CmpUnknown;
|
||||
}
|
||||
case Type::Double:
|
||||
{
|
||||
if (size >= 2) {
|
||||
union { Uint32 p[2]; double v; } u1, u2;
|
||||
u1.p[0] = p1[0];
|
||||
u1.p[1] = p1[1];
|
||||
u2.p[0] = p2[0];
|
||||
u2.p[1] = p2[1];
|
||||
if (u1.v < u2.v)
|
||||
return -1;
|
||||
if (u1.v > u2.v)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
return CmpUnknown;
|
||||
}
|
||||
case Type::Decimal:
|
||||
// XXX not used by MySQL or NDB
|
||||
break;
|
||||
case Type::Char:
|
||||
{
|
||||
/*
|
||||
* Char is blank-padded to length and null-padded to word size.
|
||||
* There is no terminator so we must compare the full values.
|
||||
*/
|
||||
union { const Uint32* p; const char* v; } u1, u2;
|
||||
u1.p = p1;
|
||||
u2.p = p2;
|
||||
int k = memcmp(u1.v, u2.v, size << 2);
|
||||
return k < 0 ? -1 : k > 0 ? +1 : full == size ? 0 : CmpUnknown;
|
||||
}
|
||||
case Type::Varchar:
|
||||
{
|
||||
/*
|
||||
* Varchar is not allowed to contain a null byte and the stored
|
||||
* value is null-padded. Therefore comparison does not need to
|
||||
* use the length.
|
||||
*/
|
||||
if (size >= 1) {
|
||||
union { const Uint32* p; const char* v; } u1, u2;
|
||||
u1.p = p1;
|
||||
u2.p = p2;
|
||||
// length in first 2 bytes
|
||||
int k = strncmp(u1.v + 2, u2.v + 2, (size << 2) - 2);
|
||||
return k < 0 ? -1 : k > 0 ? +1 : full == size ? 0 : CmpUnknown;
|
||||
}
|
||||
return CmpUnknown;
|
||||
}
|
||||
case Type::Binary:
|
||||
{
|
||||
// compare byte wise
|
||||
union { const Uint32* p; const char* v; } u1, u2;
|
||||
u1.p = p1;
|
||||
u2.p = p2;
|
||||
int k = memcmp(u1.v, u2.v, size << 2);
|
||||
return k < 0 ? -1 : k > 0 ? +1 : full == size ? 0 : CmpUnknown;
|
||||
}
|
||||
case Type::Varbinary:
|
||||
{
|
||||
// assume correctly padded and compare byte wise
|
||||
if (size >= 1) {
|
||||
union { const Uint32* p; const char* v; } u1, u2;
|
||||
u1.p = p1;
|
||||
u2.p = p2;
|
||||
// length in first 2 bytes
|
||||
int k = memcmp(u1.v + 2, u2.v + 2, (size << 2) - 2);
|
||||
return k < 0 ? -1 : k > 0 ? +1 : full == size ? 0 : CmpUnknown;
|
||||
}
|
||||
return CmpUnknown;
|
||||
}
|
||||
case Type::Datetime:
|
||||
{
|
||||
/*
|
||||
* Datetime is CC YY MM DD hh mm ss \0
|
||||
*/
|
||||
if (size >= 1) {
|
||||
union { const Uint32* p; const char* v; } u1, u2;
|
||||
u1.p = p1;
|
||||
u2.p = p2;
|
||||
// skip format check
|
||||
int k = memcmp(u1.v, u2.v, 4);
|
||||
if (k != 0)
|
||||
return k < 0 ? -1 : +1;
|
||||
if (size >= 2) {
|
||||
k = memcmp(u1.v + 4, u2.v + 4, 4);
|
||||
return k < 0 ? -1 : k > 0 ? +1 : 0;
|
||||
}
|
||||
}
|
||||
return CmpUnknown;
|
||||
}
|
||||
case Type::Timespec:
|
||||
{
|
||||
/*
|
||||
* Timespec is CC YY MM DD hh mm ss \0 NN NN NN NN
|
||||
*/
|
||||
if (size >= 1) {
|
||||
union { const Uint32* p; const char* v; } u1, u2;
|
||||
u1.p = p1;
|
||||
u2.p = p2;
|
||||
// skip format check
|
||||
int k = memcmp(u1.v, u2.v, 4);
|
||||
if (k != 0)
|
||||
return k < 0 ? -1 : +1;
|
||||
if (size >= 2) {
|
||||
k = memcmp(u1.v + 4, u2.v + 4, 4);
|
||||
if (k != 0)
|
||||
return k < 0 ? -1 : +1;
|
||||
Uint32 n1 = *(const Uint32*)(u1.v + 8);
|
||||
Uint32 n2 = *(const Uint32*)(u2.v + 8);
|
||||
if (n1 < n2)
|
||||
return -1;
|
||||
if (n2 > n1)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return CmpUnknown;
|
||||
}
|
||||
case Type::Blob:
|
||||
{
|
||||
// skip blob head, the rest is binary
|
||||
const unsigned skip = NDB_BLOB_HEAD_SIZE;
|
||||
if (size >= skip + 1) {
|
||||
union { const Uint32* p; const char* v; } u1, u2;
|
||||
u1.p = p1 + skip;
|
||||
u2.p = p2 + skip;
|
||||
int k = memcmp(u1.v, u2.v, (size - 1) << 2);
|
||||
return k < 0 ? -1 : k > 0 ? +1 : full == size ? 0 : CmpUnknown;
|
||||
}
|
||||
return CmpUnknown;
|
||||
}
|
||||
case Type::Text:
|
||||
{
|
||||
// skip blob head, the rest is char
|
||||
const unsigned skip = NDB_BLOB_HEAD_SIZE;
|
||||
if (size >= skip + 1) {
|
||||
union { const Uint32* p; const char* v; } u1, u2;
|
||||
u1.p = p1 + skip;
|
||||
u2.p = p2 + skip;
|
||||
int k = memcmp(u1.v, u2.v, (size - 1) << 2);
|
||||
return k < 0 ? -1 : k > 0 ? +1 : full == size ? 0 : CmpUnknown;
|
||||
}
|
||||
return CmpUnknown;
|
||||
}
|
||||
}
|
||||
return CmpError;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user