Commit 0019afd4 authored by Vicențiu Ciorbaru's avatar Vicențiu Ciorbaru Committed by Vicențiu Ciorbaru

Post review fixes, WIP

parent faca7b9b
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#ifndef MY_DIR_H #ifndef MY_DIR_H
#define MY_DIR_H #define MY_DIR_H
#include <my_global.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifdef __cplusplus #ifdef __cplusplus
......
...@@ -1171,7 +1171,7 @@ class Field: public Value_source ...@@ -1171,7 +1171,7 @@ class Field: public Value_source
returns the sort_length for a field without the suffix length bytes returns the sort_length for a field without the suffix length bytes
for field with binary charset. for field with binary charset.
*/ */
virtual uint32 sort_length_without_suffix() const { return pack_length(); } virtual uint32 max_storage_size_without_length_storage() const { return pack_length(); }
/* /*
sort_suffix_length() return the length bytes needed to store the length sort_suffix_length() return the length bytes needed to store the length
...@@ -4250,7 +4250,7 @@ class Field_varstring :public Field_longstr { ...@@ -4250,7 +4250,7 @@ class Field_varstring :public Field_longstr {
{ {
return (uint32) field_length + sort_suffix_length(); return (uint32) field_length + sort_suffix_length();
} }
uint32 sort_length_without_suffix() const override uint32 max_storage_size_without_length_storage() const override
{ {
return (uint32) field_length; return (uint32) field_length;
} }
...@@ -4600,7 +4600,7 @@ class Field_blob :public Field_longstr { ...@@ -4600,7 +4600,7 @@ class Field_blob :public Field_longstr {
{ return (uint32) (packlength); } { return (uint32) (packlength); }
uint row_pack_length() const override { return pack_length_no_ptr(); } uint row_pack_length() const override { return pack_length_no_ptr(); }
uint32 sort_length() const override; uint32 sort_length() const override;
uint32 sort_length_without_suffix() const override uint32 max_storage_size_without_length_storage() const override
{ {
return (uint32)field_length; return (uint32)field_length;
} }
......
...@@ -2767,6 +2767,12 @@ void SORT_FIELD::setup_key_part(Field *fld, bool is_mem_comparable_arg) ...@@ -2767,6 +2767,12 @@ void SORT_FIELD::setup_key_part(Field *fld, bool is_mem_comparable_arg)
item= NULL; item= NULL;
reverse= false; reverse= false;
SORT_FIELD_ATTR::setup_key_part(fld, is_mem_comparable_arg); SORT_FIELD_ATTR::setup_key_part(fld, is_mem_comparable_arg);
if (is_variable_sized())
key_compare_fun= SORT_FIELD::compare_packed_varstrings;
else if (is_mem_comparable)
key_compare_fun= SORT_FIELD::compare_packed_fixed_size_vals;
else
key_compare_fun= SORT_FIELD::compare_fixed_size_vals;
} }
...@@ -2782,12 +2788,10 @@ void SORT_FIELD::setup_key_part(Field *fld, bool is_mem_comparable_arg) ...@@ -2782,12 +2788,10 @@ void SORT_FIELD::setup_key_part(Field *fld, bool is_mem_comparable_arg)
*/ */
void SORT_FIELD_ATTR::setup_key_part(Field *field, bool is_mem_comparable_arg) void SORT_FIELD_ATTR::setup_key_part(Field *field, bool is_mem_comparable_arg)
{ {
original_length= length= field->sort_length_without_suffix(); original_length= length= field->max_storage_size_without_length_storage();
cs= field->sort_charset(); cs= field->sort_charset();
suffix_length= 0; suffix_length= 0;
type= field->is_packable() ? type= field->is_packable() ? VARIABLE_SIZE : FIXED_SIZE;
SORT_FIELD_ATTR::VARIABLE_SIZE :
SORT_FIELD_ATTR::FIXED_SIZE;
maybe_null= field->maybe_null(); maybe_null= field->maybe_null();
is_mem_comparable= is_mem_comparable_arg; is_mem_comparable= is_mem_comparable_arg;
length_bytes= is_variable_sized() ? number_storage_requirement(length) : 0; length_bytes= is_variable_sized() ? number_storage_requirement(length) : 0;
...@@ -2809,25 +2813,6 @@ void SORT_FIELD_ATTR::setup_key_part(Field *field, bool is_mem_comparable_arg) ...@@ -2809,25 +2813,6 @@ void SORT_FIELD_ATTR::setup_key_part(Field *field, bool is_mem_comparable_arg)
0 either key a and key b are both NULL or both are NOT NULL 0 either key a and key b are both NULL or both are NOT NULL
*/ */
enum null_comparison_result {
BOTH_NULL,
A_NULL,
B_NULL,
BOTH_NOT_NULL
};
inline enum null_comparison_result compare_null_flag(bool a_null,
bool b_null)
{
if (a_null && b_null)
return BOTH_NULL;
if (a_null)
return A_NULL;
if (b_null)
return B_NULL;
return BOTH_NOT_NULL;
}
/* /*
Compare two keys. Compare two keys.
...@@ -2849,33 +2834,29 @@ int SORT_FIELD::compare_keys(const uchar *a, size_t *a_len, ...@@ -2849,33 +2834,29 @@ int SORT_FIELD::compare_keys(const uchar *a, size_t *a_len,
const uchar *b, size_t *b_len) const const uchar *b, size_t *b_len) const
{ {
int result; int result;
bool a_null = !*a;
bool b_null = !*b;
if (maybe_null) if (maybe_null)
{ {
/* In sort keys (or packed keys) null_byte is 0 if the key is null. */ if (a_null)
switch (compare_null_flag(!*a, !*b)) {
case BOTH_NULL:
{ {
if (b_null)
{
// Null byte is always stored. // Null byte is always stored.
*a_len= *b_len= 1; *a_len= *b_len= 1;
return 0; return 0;
} }
case A_NULL:
return -1; return -1;
case B_NULL:
return 1;
default:
break;
} }
if (b_null)
return 1;
a++; a++;
b++; b++;
} }
if (is_variable_sized()) result= key_compare_fun(this, a, a_len, b, b_len);
result= compare_packed_varstrings(a, a_len, b, b_len);
else if (is_mem_comparable)
result= compare_packed_fixed_size_vals(a, a_len, b, b_len);
else
result= compare_fixed_size_vals(a, a_len, b, b_len);
// Null byte is always stored. // Null byte is always stored.
if (result == 0 && maybe_null) if (result == 0 && maybe_null)
...@@ -2887,25 +2868,28 @@ int SORT_FIELD::compare_keys(const uchar *a, size_t *a_len, ...@@ -2887,25 +2868,28 @@ int SORT_FIELD::compare_keys(const uchar *a, size_t *a_len,
} }
int SORT_FIELD::compare_packed_varstrings(const uchar *a, size_t *a_len, int SORT_FIELD::compare_packed_varstrings(const SORT_FIELD *sort_field,
const uchar *b, size_t *b_len) const const uchar *a, size_t *a_len,
const uchar *b, size_t *b_len)
{ {
int retval; int retval;
size_t a_length, b_length; size_t a_length, b_length;
uint length_bytes= sort_field->length_bytes;
uint suffix_length= sort_field->suffix_length;
a_length= read_key_part_length(a, length_bytes); a_length= read_key_part_length(a, length_bytes);
b_length= read_key_part_length(b, length_bytes); b_length= read_key_part_length(b, length_bytes);
*a_len= length_bytes + a_length; *a_len= length_bytes + a_length;
*b_len= length_bytes + b_length; *b_len= length_bytes + b_length;
retval= cs->strnncollsp(a + length_bytes, retval= sort_field->cs->strnncollsp(a + length_bytes,
a_length - suffix_length, a_length - suffix_length,
b + length_bytes, b + length_bytes,
b_length - suffix_length); b_length - suffix_length);
if (!retval && suffix_length) if (!retval && suffix_length)
{ {
DBUG_ASSERT(cs == &my_charset_bin); DBUG_ASSERT(sort_field->cs == &my_charset_bin);
// comparing the length stored in suffix bytes for binary strings // comparing the length stored in suffix bytes for binary strings
a= a + length_bytes + a_length - suffix_length; a= a + length_bytes + a_length - suffix_length;
b= b + length_bytes + b_length - suffix_length; b= b + length_bytes + b_length - suffix_length;
...@@ -2916,20 +2900,22 @@ int SORT_FIELD::compare_packed_varstrings(const uchar *a, size_t *a_len, ...@@ -2916,20 +2900,22 @@ int SORT_FIELD::compare_packed_varstrings(const uchar *a, size_t *a_len,
} }
int SORT_FIELD::compare_packed_fixed_size_vals(const uchar *a, size_t *a_len, int SORT_FIELD::compare_packed_fixed_size_vals(const SORT_FIELD *sort_field,
const uchar *b, size_t *b_len) const const uchar *a, size_t *a_len,
const uchar *b, size_t *b_len)
{ {
*a_len= length; *a_len= sort_field->length;
*b_len= length; *b_len= sort_field->length;
return memcmp(a, b, length); return memcmp(a, b, sort_field->length);
} }
int SORT_FIELD::compare_fixed_size_vals(const uchar *a, size_t *a_len, int SORT_FIELD::compare_fixed_size_vals(const SORT_FIELD *sort_field,
const uchar *b, size_t *b_len) const const uchar *a, size_t *a_len,
const uchar *b, size_t *b_len)
{ {
*a_len= length; *a_len= sort_field->length;
*b_len= length; *b_len= sort_field->length;
return field->cmp(a, b); return sort_field->field->cmp(a, b);
} }
......
...@@ -4191,7 +4191,7 @@ bool Item_func_group_concat::add(bool exclude_nulls) ...@@ -4191,7 +4191,7 @@ bool Item_func_group_concat::add(bool exclude_nulls)
row to the output buffer here. That will be done in val_str. row to the output buffer here. That will be done in val_str.
*/ */
if (!warning_for_row && (!tree && !distinct)) if (!warning_for_row && (!tree && !distinct))
dump_leaf_key(get_record_pointer(), 1, this); this->dump_leaf_key_impl(get_record_pointer(), false);
return 0; return 0;
} }
...@@ -4535,11 +4535,11 @@ bool Item_sum::is_packing_allowed(uint *total_length) const ...@@ -4535,11 +4535,11 @@ bool Item_sum::is_packing_allowed(uint *total_length) const
// 1 byte for nullability; // 1 byte for nullability;
tot_length+= MY_TEST(field->maybe_null()); tot_length+= MY_TEST(field->maybe_null());
tot_length+= field->sort_length_without_suffix(); tot_length+= field->max_storage_size_without_length_storage();
if (field->is_packable()) if (field->is_packable())
{ {
size_of_packable_fields+= size_of_packable_fields+= number_storage_requirement(
number_storage_requirement(field->sort_length_without_suffix()); field->max_storage_size_without_length_storage());
} }
} }
} }
......
...@@ -7381,12 +7381,19 @@ struct SORT_FIELD: public SORT_FIELD_ATTR ...@@ -7381,12 +7381,19 @@ struct SORT_FIELD: public SORT_FIELD_ATTR
const uchar *b, size_t *b_len) const; const uchar *b, size_t *b_len) const;
private: private:
int compare_fixed_size_vals(const uchar *a, size_t *a_len, typedef int (*compare_fun_type) (const SORT_FIELD *,
const uchar *b, size_t *b_len) const; const uchar *, size_t *,
int compare_packed_fixed_size_vals(const uchar *a, size_t *a_len, const uchar *, size_t *);
const uchar *b, size_t *b_len) const; compare_fun_type key_compare_fun = nullptr;
int compare_packed_varstrings(const uchar *a, size_t *a_len, static int compare_fixed_size_vals(const SORT_FIELD *sort_field,
const uchar *b, size_t *b_len) const; const uchar *a, size_t *a_len,
const uchar *b, size_t *b_len);
static int compare_packed_fixed_size_vals(const SORT_FIELD *sort_field,
const uchar *a, size_t *a_len,
const uchar *b, size_t *b_len);
static int compare_packed_varstrings(const SORT_FIELD *sort_field,
const uchar *a, size_t *a_len,
const uchar *b, size_t *b_len);
}; };
......
...@@ -53,19 +53,21 @@ int Unique::unique_write_to_file_with_count(uchar* key, element_count count, ...@@ -53,19 +53,21 @@ int Unique::unique_write_to_file_with_count(uchar* key, element_count count,
my_b_write(&unique->file, (uchar*)&count, sizeof(element_count)) ? 1 : 0; my_b_write(&unique->file, (uchar*)&count, sizeof(element_count)) ? 1 : 0;
} }
int Unique::unique_write_to_ptrs(uchar* key, element_count count, Unique *unique) int Unique::unique_write_to_ptrs(uchar* key, element_count count,
Unique *unique)
{ {
memcpy(unique->sort.record_pointers, key, unique->size); memcpy(unique->sort.record_pointers, key, unique->size);
unique->sort.record_pointers+=unique->size; unique->sort.record_pointers+=unique->size;
return 0; return 0;
} }
int Unique::unique_intersect_write_to_ptrs(uchar* key, element_count count, Unique *unique) int Unique::unique_intersect_write_to_ptrs(uchar* key, element_count count,
Unique *unique)
{ {
if (count >= unique->min_dupl_count) if (count >= unique->min_dupl_count)
{ {
memcpy(unique->sort.record_pointers, key, unique->size); memcpy(unique->sort.record_pointers, key, unique->size);
unique->sort.record_pointers+=unique->size; unique->sort.record_pointers+= unique->size;
} }
else else
unique->filtered_out_elems++; unique->filtered_out_elems++;
...@@ -76,11 +78,11 @@ int Unique::unique_intersect_write_to_ptrs(uchar* key, element_count count, Uniq ...@@ -76,11 +78,11 @@ int Unique::unique_intersect_write_to_ptrs(uchar* key, element_count count, Uniq
Unique::Unique(Keys_descriptor *desc, Unique::Unique(Keys_descriptor *desc,
size_t max_in_memory_size_arg, size_t max_in_memory_size_arg,
uint min_dupl_count_arg) uint min_dupl_count_arg)
:max_in_memory_size(max_in_memory_size_arg), :size(desc->get_max_key_length()),
size(desc->get_max_key_length()), max_in_memory_size(max_in_memory_size_arg),
max_elements(max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+size)),
full_size(min_dupl_count_arg ? size + sizeof(element_count) : size), full_size(min_dupl_count_arg ? size + sizeof(element_count) : size),
min_dupl_count(min_dupl_count_arg), min_dupl_count(min_dupl_count_arg),
with_counters(MY_TEST(min_dupl_count_arg)),
memory_used(0), memory_used(0),
elements(0), elements(0),
keys_descriptor(desc) keys_descriptor(desc)
...@@ -88,14 +90,9 @@ Unique::Unique(Keys_descriptor *desc, ...@@ -88,14 +90,9 @@ Unique::Unique(Keys_descriptor *desc,
my_b_clear(&file); my_b_clear(&file);
init_tree(&tree, (max_in_memory_size / 16), 0, 0, unique_compare_keys, init_tree(&tree, (max_in_memory_size / 16), 0, 0, unique_compare_keys,
NULL, desc, MYF(MY_THREAD_SPECIFIC)); NULL, desc, MYF(MY_THREAD_SPECIFIC));
/* If the following fail's the next add will also fail */ /* If the following fails the next add will also fail */
my_init_dynamic_array(PSI_INSTRUMENT_ME, &file_ptrs, sizeof(Merge_chunk), 16, my_init_dynamic_array(PSI_INSTRUMENT_ME, &file_ptrs, sizeof(Merge_chunk), 16,
16, MYF(MY_THREAD_SPECIFIC)); 16, MYF(MY_THREAD_SPECIFIC));
/*
If you change the following, change it in get_max_elements function, too.
*/
max_elements= (ulong) (max_in_memory_size /
ALIGN_SIZE(sizeof(TREE_ELEMENT)+size));
if (!max_elements) if (!max_elements)
{ {
max_elements= 1; max_elements= 1;
...@@ -382,7 +379,7 @@ Unique::~Unique() ...@@ -382,7 +379,7 @@ Unique::~Unique()
} }
/* Write tree to disk; clear tree */ /* Write tree to disk; clear tree */
bool Unique::flush() bool Unique::flush()
{ {
Merge_chunk file_ptr; Merge_chunk file_ptr;
...@@ -393,8 +390,7 @@ bool Unique::flush() ...@@ -393,8 +390,7 @@ bool Unique::flush()
tree_walk_action action= min_dupl_count ? tree_walk_action action= min_dupl_count ?
(tree_walk_action) unique_write_to_file_with_count : (tree_walk_action) unique_write_to_file_with_count :
(tree_walk_action) unique_write_to_file; (tree_walk_action) unique_write_to_file;
if (tree_walk(&tree, action, if (tree_walk(&tree, action, (void*) this, left_root_right) ||
(void*) this, left_root_right) ||
insert_dynamic(&file_ptrs, (uchar*) &file_ptr)) insert_dynamic(&file_ptrs, (uchar*) &file_ptr))
return 1; return 1;
/** /**
...@@ -699,7 +695,7 @@ bool Unique::walk(TABLE *table, tree_walk_action action, void *walk_action_arg) ...@@ -699,7 +695,7 @@ bool Unique::walk(TABLE *table, tree_walk_action action, void *walk_action_arg)
(Merge_chunk *) file_ptrs.buffer, (Merge_chunk *) file_ptrs.buffer,
(Merge_chunk *) file_ptrs.buffer + file_ptrs.elements, (Merge_chunk *) file_ptrs.buffer + file_ptrs.elements,
action, walk_action_arg, action, walk_action_arg,
tree.compare, tree.custom_arg, &file, with_counters, tree.compare, tree.custom_arg, &file, is_count_stored(),
min_dupl_count, is_variable_sized()); min_dupl_count, is_variable_sized());
} }
my_free(merge_buffer); my_free(merge_buffer);
......
...@@ -237,14 +237,14 @@ class Unique : public Sql_alloc ...@@ -237,14 +237,14 @@ class Unique : public Sql_alloc
{ {
DYNAMIC_ARRAY file_ptrs; DYNAMIC_ARRAY file_ptrs;
/* Total number of elements that will be stored in-memory */ /* Total number of elements that will be stored in-memory */
ulong max_elements; uint size;
size_t max_in_memory_size; size_t max_in_memory_size;
size_t max_elements;
IO_CACHE file; IO_CACHE file;
TREE tree; TREE tree;
/* Number of elements filtered out due to min_dupl_count when storing results /* Number of elements filtered out due to min_dupl_count when storing results
to table. See Unique::get */ to table. See Unique::get */
ulong filtered_out_elems; ulong filtered_out_elems;
uint size;
const uint full_size; /* Size of element + space needed to store the number of const uint full_size; /* Size of element + space needed to store the number of
duplicates found for the element. */ duplicates found for the element. */
...@@ -252,7 +252,6 @@ class Unique : public Sql_alloc ...@@ -252,7 +252,6 @@ class Unique : public Sql_alloc
required for it to be written to required for it to be written to
record_pointers. record_pointers.
always 0 for unions, > 0 for intersections */ always 0 for unions, > 0 for intersections */
const bool with_counters;
// size in bytes used for storing keys in the Unique tree // size in bytes used for storing keys in the Unique tree
size_t memory_used; size_t memory_used;
...@@ -297,7 +296,7 @@ class Unique : public Sql_alloc ...@@ -297,7 +296,7 @@ class Unique : public Sql_alloc
bool unique_add(void *ptr, uint key_size) bool unique_add(void *ptr, uint key_size)
{ {
DBUG_ENTER("unique_add"); DBUG_ENTER("unique_add");
DBUG_PRINT("info", ("tree %u - %lu", tree.elements_in_tree, max_elements)); DBUG_PRINT("info", ("tree %u - %zu", tree.elements_in_tree, max_elements));
TREE_ELEMENT *res; TREE_ELEMENT *res;
size_t rec_size= key_size + sizeof(TREE_ELEMENT) + tree.size_of_element; size_t rec_size= key_size + sizeof(TREE_ELEMENT) + tree.size_of_element;
...@@ -378,7 +377,7 @@ class Unique : public Sql_alloc ...@@ -378,7 +377,7 @@ class Unique : public Sql_alloc
uint get_size() const { return size; } uint get_size() const { return size; }
uint get_full_size() const { return full_size; } uint get_full_size() const { return full_size; }
bool is_count_stored() { return with_counters; } bool is_count_stored() { return min_dupl_count; }
int write_record_to_file(uchar *key); int write_record_to_file(uchar *key);
size_t get_max_in_memory_size() const { return max_in_memory_size; } size_t get_max_in_memory_size() const { return max_in_memory_size; }
......
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