Commit 02b7ae99 authored by Zardosht Kasheff's avatar Zardosht Kasheff Committed by Yoni Fogel

addresses #772

git-svn-id: file:///svn/mysql/tokudb-engine/src@3818 c7de825b-a66e-492c-adef-691d508d4ae1
parent 3144ecd8
......@@ -3003,52 +3003,88 @@ double ha_tokudb::scan_time() {
}
//
// Estimates the number of index records in a range.
// Estimates the number of index records in a range. In case of errors, return
// HA_TOKUDB_RANGE_COUNT instead of HA_POS_ERROR. This was behavior
// when we got the handlerton from MySQL.
// Parameters:
// keynr -index to use
// [in] start_key - low end of the range
// [in] end_key - high end of the range
// Returns:
// 0 - There are no matching keys in the given range
// number > 0 - There are approximately number matching rows in the range
// HA_POS_ERROR - Something is wrong with the index tree
//
ha_rows ha_tokudb::records_in_range(uint keynr, key_range * start_key, key_range * end_key) {
ha_rows ha_tokudb::records_in_range(uint keynr, key_range* start_key, key_range* end_key) {
TOKUDB_DBUG_ENTER("ha_tokudb::records_in_range");
#if 0 // QQQ need key_range
DBT key;
ha_rows ret_val = HA_TOKUDB_RANGE_COUNT;
DB_KEY_RANGE start_range, end_range;
DB *kfile = key_file[keynr];
double start_pos, end_pos, rows;
bool error;
double start_frac, end_frac, rows;
int error;
KEY *key_info = &table->key_info[keynr];
/* Ensure we get maximum range, even for varchar keys with different space */
assert(0);
key_info->handler.bdb_return_if_eq = -1;
error = ((start_key && kfile->key_range(kfile, transaction, pack_key(&key, keynr, key_buff, start_key->key, start_key->length), &start_range, 0)));
if (error) {
key_info->handler.bdb_return_if_eq = 0;
// Better than returning an error
TOKUDB_DBUG_RETURN(HA_TOKUDB_RANGE_COUNT);
//
// get start_frac and end_frac values so that we can estimate range
//
if (start_key) {
error = kfile->key_range(
kfile,
transaction,
pack_key(&key, keynr, key_buff, start_key->key, start_key->length),
&start_range,
0
);
if (error) {
ret_val = HA_TOKUDB_RANGE_COUNT;
goto cleanup;
}
if (start_key->flag == HA_READ_KEY_EXACT) {
start_frac = start_range.less;
}
else {
start_frac = start_range.less + start_range.equal;
}
}
assert(0);
key_info->handler.bdb_return_if_eq = 1;
error = (end_key && kfile->key_range(kfile, transaction, pack_key(&key, keynr, key_buff, end_key->key, end_key->length), &end_range, 0));
key_info->handler.bdb_return_if_eq = 0;
if (error) {
// Better than returning an error
TOKUDB_DBUG_RETURN(HA_TOKUDB_RANGE_COUNT);
}
if (!start_key)
start_pos = 0.0;
else if (start_key->flag == HA_READ_KEY_EXACT)
start_pos = start_range.less;
else
start_pos = start_range.less + start_range.equal;
if (!end_key)
end_pos = 1.0;
else if (end_key->flag == HA_READ_BEFORE_KEY)
end_pos = end_range.less;
else
end_pos = end_range.less + end_range.equal;
rows = (end_pos - start_pos) * stats.records;
else {
start_frac = 0.0
}
if (end_key) {
error = kfile->key_range(
kfile,
transaction,
pack_key(&key, keynr, key_buff, end_key->key, end_key->length),
&end_range,
0
);
if (error) {
ret_val = HA_TOKUDB_RANGE_COUNT;
goto cleanup;
}
if (end_key->flag == HA_READ_BEFORE_KEY) {
end_frac = end_range.less;
}
else {
end_frac = end_range.less + end_range.equal;
}
}
else {
end_frac = 1.0;
}
//
// end_frac and start_frac give fractions of values over stats.records
// to return estimate multiply by stats.records
//
rows = (end_frac - start_frac) * stats.records;
DBUG_PRINT("exit", ("rows: %g", rows));
TOKUDB_DBUG_RETURN((ha_rows) (rows <= 1.0 ? 1 : rows));
ret_val = (ha_rows) (rows <= 1.0 ? 1 : rows);
cleanup:
TOKUDB_DBUG_RETURN(ret_val);
#else
TOKUDB_DBUG_RETURN(HA_TOKUDB_RANGE_COUNT);
#endif
......
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