8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 20:43:02 +01:00

bugfix in delete_node

litlle optimization in compress() function
This commit is contained in:
arnobrinkman 2004-09-27 22:42:56 +00:00
parent 9f9d995f44
commit 9d63050cf4

View File

@ -1989,76 +1989,82 @@ static void compress(thread_db* tdbb,
const UCHAR desc_end_value_prefix = 0x01; // ~0xFE
const UCHAR desc_end_value_check = 0x00; // ~0xFF;
SET_TDBB(tdbb);
const Database* dbb = tdbb->tdbb_database;
CHECK_DBB(dbb);
UCHAR* p = key->key_data;
if (isNull && dbb->dbb_ods_version >= ODS_VERSION7) {
UCHAR pad = 0;
key->key_flags &= ~key_empty;
// AB: NULL should be threated as lowest value possible.
// Therefore don't complement pad when we have an
// ascending index.
if (dbb->dbb_ods_version < ODS_VERSION11) {
if (!descending) {
pad ^= -1;
}
}
else {
if (descending) {
// DESC NULLs are stored as 1 byte
*p++ = pad;
key->key_length = (p - key->key_data);
return;
if (isNull) {
if (dbb->dbb_ods_version >= ODS_VERSION7) {
UCHAR pad = 0;
key->key_flags &= ~key_empty;
// AB: NULL should be threated as lowest value possible.
// Therefore don't complement pad when we have an
// ascending index.
if (dbb->dbb_ods_version < ODS_VERSION11) {
if (!descending) {
pad ^= -1;
}
}
else {
// ASC NULLs are stored with no data
key->key_length = 0;
return;
if (descending) {
// DESC NULLs are stored as 1 byte
*p++ = pad;
key->key_length = (p - key->key_data);
return;
}
else {
// ASC NULLs are stored with no data
key->key_length = 0;
return;
}
}
}
size_t length;
switch (itype)
{
case idx_numeric:
length = sizeof(double);
break;
case idx_sql_time:
length = sizeof(ULONG);
break;
case idx_sql_date:
length = sizeof(SLONG);
break;
case idx_timestamp2:
length = sizeof(SINT64);
break;
case idx_numeric2:
length = INT64_KEY_LENGTH;
break;
default:
length = desc->dsc_length;
if (desc->dsc_dtype == dtype_varying) {
length -= sizeof(SSHORT);
size_t length;
switch (itype)
{
case idx_numeric:
length = sizeof(double);
break;
case idx_sql_time:
length = sizeof(ULONG);
break;
case idx_sql_date:
length = sizeof(SLONG);
break;
case idx_timestamp2:
length = sizeof(SINT64);
break;
case idx_numeric2:
length = INT64_KEY_LENGTH;
break;
default:
length = desc->dsc_length;
if (desc->dsc_dtype == dtype_varying) {
length -= sizeof(SSHORT);
}
if (itype >= idx_first_intl_string) {
length = INTL_key_length(tdbb, itype, length);
}
break;
}
if (itype >= idx_first_intl_string) {
length = INTL_key_length(tdbb, itype, length);
length = (length > sizeof(key->key_data)) ? sizeof(key->key_data) : length;
while (length--) {
*p++ = pad;
}
break;
key->key_length = (p - key->key_data);
return;
}
length = (length > sizeof(key->key_data)) ? sizeof(key->key_data) : length;
while (length--) {
*p++ = pad;
else {
// for dbb->dbb_ods_version < ODS_VERSION7
key->key_flags &= ~key_empty;
memset(&temp, 0, sizeof(temp));
}
key->key_length = (p - key->key_data);
return;
}
if (itype == idx_string ||
itype == idx_byte_array ||
itype == idx_metadata || itype >= idx_first_intl_string)
itype == idx_metadata ||
itype >= idx_first_intl_string)
{
UCHAR temp1[MAX_KEY];
const UCHAR pad = (itype == idx_string) ? ' ' : 0;
@ -2134,38 +2140,13 @@ static void compress(thread_db* tdbb,
key->key_flags &= ~key_empty;
size_t temp_copy_length = sizeof(double);
if (isNull) {
memset(&temp, 0, sizeof(temp));
}
if (itype == idx_timestamp2) {
GDS_TIMESTAMP timestamp;
timestamp = MOV_get_timestamp(desc);
const ULONG SECONDS_PER_DAY = 24 * 60 * 60;
temp.temp_sint64 = ((SINT64) (timestamp.timestamp_date) *
(SINT64) (SECONDS_PER_DAY * ISC_TIME_SECONDS_PRECISION)) +
(SINT64) (timestamp.timestamp_time);
temp_copy_length = sizeof(SINT64);
if (itype == idx_numeric) {
temp.temp_double = MOV_get_double(desc);
temp_is_negative = (temp.temp_double < 0);
#ifdef DEBUG_INDEXKEY
fprintf(stderr, "TIMESTAMP2: %d:%u ",
((const SLONG*) desc->dsc_address)[0],
((const ULONG*) desc->dsc_address)[1]);
fprintf(stderr, "TIMESTAMP2: %20" QUADFORMAT "d ",
temp.temp_sint64);
#endif
}
else if (itype == idx_sql_date) {
temp.temp_slong = MOV_get_sql_date(desc);
temp_copy_length = sizeof(SLONG);
#ifdef DEBUG_INDEXKEY
fprintf(stderr, "DATE %d ", temp.temp_slong);
#endif
}
else if (itype == idx_sql_time) {
temp.temp_ulong = MOV_get_sql_time(desc);
temp_copy_length = sizeof(ULONG);
temp_is_negative = false;
#ifdef DEBUG_INDEXKEY
fprintf(stderr, "TIME %u ", temp.temp_ulong);
fprintf(stderr, "NUMERIC %lg ", temp.temp_double);
#endif
}
else if (itype == idx_numeric2) {
@ -2174,10 +2155,49 @@ static void compress(thread_db* tdbb,
make_int64_key(MOV_get_int64(desc, desc->dsc_scale), desc->dsc_scale);
temp_copy_length = sizeof(temp.temp_int64_key.d_part);
temp_is_negative = (temp.temp_int64_key.d_part < 0);
#ifdef DEBUG_INDEXKEY
print_int64_key(*(const SINT64*) desc->dsc_address,
desc->dsc_scale, temp.temp_int64_key);
#endif
}
else if (itype == idx_timestamp2) {
GDS_TIMESTAMP timestamp;
timestamp = MOV_get_timestamp(desc);
const ULONG SECONDS_PER_DAY = 24 * 60 * 60;
temp.temp_sint64 = ((SINT64) (timestamp.timestamp_date) *
(SINT64) (SECONDS_PER_DAY * ISC_TIME_SECONDS_PRECISION)) +
(SINT64) (timestamp.timestamp_time);
temp_copy_length = sizeof(SINT64);
#ifdef DEBUG_INDEXKEY
fprintf(stderr, "TIMESTAMP2: %d:%u ",
((const SLONG*) desc->dsc_address)[0],
((const ULONG*) desc->dsc_address)[1]);
fprintf(stderr, "TIMESTAMP2: %20" QUADFORMAT "d ",
temp.temp_sint64);
#endif
}
else if (itype == idx_sql_date) {
temp.temp_slong = MOV_get_sql_date(desc);
temp_copy_length = sizeof(SLONG);
#ifdef DEBUG_INDEXKEY
fprintf(stderr, "DATE %d ", temp.temp_slong);
#endif
}
else if (itype == idx_sql_time) {
temp.temp_ulong = MOV_get_sql_time(desc);
temp_copy_length = sizeof(ULONG);
temp_is_negative = false;
#ifdef DEBUG_INDEXKEY
fprintf(stderr, "TIME %u ", temp.temp_ulong);
#endif
}
else if (desc->dsc_dtype == dtype_timestamp) {
// This is the same as the pre v6 behavior. Basically, the
@ -2186,16 +2206,20 @@ static void compress(thread_db* tdbb,
// eg: WHERE anInteger = TIMESTAMP '1998-9-16'
temp.temp_double = MOV_date_to_double(desc);
temp_is_negative = (temp.temp_double < 0);
#ifdef DEBUG_INDEXKEY
fprintf(stderr, "TIMESTAMP1 special %lg ", temp.temp_double);
#endif
}
else {
temp.temp_double = MOV_get_double(desc);
temp_is_negative = (temp.temp_double < 0);
#ifdef DEBUG_INDEXKEY
fprintf(stderr, "NUMERIC %lg ", temp.temp_double);
#endif
}
#ifdef IEEE
@ -2203,13 +2227,46 @@ static void compress(thread_db* tdbb,
const UCHAR* q;
#ifndef WORDS_BIGENDIAN
// For little-endian machines, reverse the order of bytes for the key
// Copy the first set of bytes into key_data
size_t length = temp_copy_length;
/*
AB: Speed things a little up, remember that this is function is called a lot.
for (q = temp.temp_char + temp_copy_length; length; --length)
{
*p++ = *--q;
}
*/
q = temp.temp_char + temp_copy_length;
while (length) {
if (length >= 8) {
q -= 8;
p[0] = q[7];
p[1] = q[6];
p[2] = q[5];
p[3] = q[4];
p[4] = q[3];
p[5] = q[2];
p[6] = q[1];
p[7] = q[0];
p += 8;
length -= 8;
}
else if (length >= 4) {
q -= 4;
p[0] = q[3];
p[1] = q[2];
p[2] = q[1];
p[3] = q[0];
p += 4;
length -= 4;
}
else {
*p++ = *--q;
length--;
}
}
// Copy the next 2 bytes into key_data, if key is of an int64 type
if (int64_key_op) {
@ -2289,21 +2346,22 @@ static void compress(thread_db* tdbb,
key->key_data[0] ^= 1 << 7;
}
// Complement the s_part for an int64 key.
// If we just flip the sign bit, which is equivalent to adding 32768, the
// short part will unsigned-compare correctly.
if (int64_key_op) {
// Complement the s_part for an int64 key.
// If we just flip the sign bit, which is equivalent to adding 32768, the
// short part will unsigned-compare correctly.
key->key_data[8] ^= 1 << 7;
/*p = &key->key_data[(!int64_key_op) ? temp_copy_length - 1 : INT64_KEY_LENGTH - 1];*/
p = &key->key_data[INT64_KEY_LENGTH - 1];
}
else {
p = &key->key_data[temp_copy_length - 1];
}
// Finally, chop off trailing binary zeros
for (p = &key->key_data[(!int64_key_op) ?
temp_copy_length - 1 : INT64_KEY_LENGTH - 1];
p > key->key_data; --p)
{
if (*p) {
break;
}
while (!(*p) && (p > key->key_data)) {
--p;
}
key->key_length = (p - key->key_data) + 1;
@ -5820,7 +5878,7 @@ static CONTENTS remove_leaf_node(thread_db* tdbb, index_insertion* insertion, WI
while (true) {
// if we find the right one, quit
if (insertion->iib_number == node.recordNumber) {
if (insertion->iib_number == node.recordNumber && !node.isEndBucket) {
break;
}