Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
2f9484c6
Commit
2f9484c6
authored
Sep 24, 2024
by
Nikita Malyavin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
optimize hash api to allow "insert if not found"
parent
e0b0a12e
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
83 additions
and
48 deletions
+83
-48
include/open_address_hash.h
include/open_address_hash.h
+51
-30
sql/mdl.cc
sql/mdl.cc
+1
-1
sql/sql_base.cc
sql/sql_base.cc
+31
-17
No files found.
include/open_address_hash.h
View file @
2f9484c6
...
...
@@ -64,20 +64,32 @@ class Open_address_hash
return
Key_trait
::
get_hash_value
(
get_key
(
value
));
}
bool
insert_into_bucket
(
const
Value
&
value
)
template
<
typename
ElemSuitsFunc
,
typename
GetElemFunc
>
bool
insert_into_bucket
(
const
Key
&
key
,
const
ElemSuitsFunc
&
elem_suits
,
const
GetElemFunc
&
get_elem
)
{
auto
hash_val
=
to_index
(
hash_from_value
(
value
));
auto
hash_val
=
to_index
(
Key_trait
::
get_hash_value
(
&
key
));
while
(
!
is_empty
(
hash_array
[
hash_val
]))
{
if
(
is_equal
(
hash_array
[
hash_val
],
value
))
if
(
elem_suits
(
hash_array
[
hash_val
]
))
return
false
;
hash_val
=
to_index
(
hash_val
+
1
);
}
hash_array
[
hash_val
]
=
value
;
return
true
;
};
Value
&&
value
=
get_elem
();
hash_array
[
hash_val
]
=
get_elem
();
return
!
is_empty
(
value
);
}
bool
insert_into_bucket
(
const
Value
&
value
)
{
return
insert_into_bucket
(
*
get_key
(
value
),
[
&
value
](
const
Value
&
rhs
){
return
is_equal
(
rhs
,
value
);
},
[
&
value
](){
return
value
;
}
);
}
uint
rehash_subsequence
(
uint
i
)
{
...
...
@@ -175,7 +187,7 @@ class Open_address_hash
public:
Value
find
(
const
Value
&
elem
)
const
{
return
find
(
*
Key_trait
::
get_key
(
elem
),
return
find
(
*
get_key
(
elem
),
[
&
elem
](
const
Value
&
rhs
)
{
return
is_equal
(
rhs
,
elem
);
});
}
...
...
@@ -184,12 +196,9 @@ class Open_address_hash
{
if
(
likely
(
first
.
mark
()))
{
if
(
first
.
ptr
())
{
if
(
elem_suits
(
first
.
ptr
()))
return
first
.
ptr
();
}
else
if
(
!
is_empty
(
second
)
&&
elem_suits
(
second
))
if
(
!
is_empty
(
first
.
ptr
())
&&
elem_suits
(
first
.
ptr
()))
return
first
.
ptr
();
if
(
!
is_empty
(
second
)
&&
elem_suits
(
second
))
return
second
;
return
EMPTY
;
...
...
@@ -203,7 +212,7 @@ class Open_address_hash
}
return
EMPTY
;
}
;
}
bool
erase
(
const
Value
&
value
)
{
...
...
@@ -215,7 +224,7 @@ class Open_address_hash
second
=
EMPTY
;
return
true
;
}
else
if
(
second
&&
is_equal
(
second
,
value
))
else
if
(
!
is_empty
(
second
)
&&
is_equal
(
second
,
value
))
{
second
=
EMPTY
;
return
true
;
...
...
@@ -235,30 +244,35 @@ class Open_address_hash
return
true
;
}
bool
insert
(
const
Value
&
value
)
template
<
typename
ElemSuitsFunc
,
typename
GetElemFunc
>
bool
insert
(
const
Key
&
key
,
const
ElemSuitsFunc
&
elem_suits
,
const
GetElemFunc
&
get_elem
)
{
if
(
first
.
mark
())
{
if
(
is_empty
(
first
.
ptr
()))
{
if
(
is_equal
(
second
,
value
))
return
false
;
first
.
set_ptr
(
value
);
first
.
set_ptr
(
get_elem
());
return
true
;
}
else
if
(
is_empty
(
second
))
{
if
(
is_equal
(
first
.
ptr
(),
value
))
return
false
;
second
=
value
;
if
(
elem_suits
(
first
.
ptr
()))
return
true
;
}
else
if
(
is_empty
(
second
))
{
first
.
set_mark
(
false
);
if
(
!
init_hash_array
())
return
false
;
second
=
get_elem
();
return
true
;
}
if
(
elem_suits
(
second
))
return
true
;
first
.
set_mark
(
false
);
if
(
!
init_hash_array
())
return
false
;
}
if
(
unlikely
(
_size
==
TABLE_SIZE_MAX
))
...
...
@@ -269,12 +283,19 @@ class Open_address_hash
if
(
unlikely
(((
ulonglong
)
_size
+
1
)
*
MAX_LOAD_FACTOR
>
capacity
))
res
=
grow
(
capacity_power
+
1
);
res
=
res
&&
insert_into_bucket
(
value
);
res
=
res
&&
insert_into_bucket
(
key
,
elem_suits
,
get_elem
);
if
(
res
)
_size
++
;
return
res
;
};
bool
insert
(
const
Value
&
value
)
{
return
insert
(
*
get_key
(
value
),
[
&
value
](
const
Value
&
rhs
){
return
is_equal
(
rhs
,
value
);
},
[
&
value
](){
return
value
;
});
}
bool
clear
()
{
if
(
first
.
mark
())
...
...
sql/mdl.cc
View file @
2f9484c6
...
...
@@ -1964,7 +1964,7 @@ MDL_context::find_ticket(MDL_request *mdl_request,
t
->
m_duration
==
mdl_request
->
duration
;
};
MDL_ticket
*
found_ticket
=
ticket_hash
.
find
(
&
mdl_request
->
key
,
MDL_ticket
*
found_ticket
=
ticket_hash
.
find
(
mdl_request
->
key
,
ticket_identical
);
if
(
!
found_ticket
)
{
...
...
sql/sql_base.cc
View file @
2f9484c6
...
...
@@ -5053,27 +5053,41 @@ prepare_fk_prelocking_list(THD *thd, Query_tables_list *prelocking_ctx,
else
lock_type
=
TL_READ
;
MDL_key
key
(
MDL_key
::
TABLE
,
fk
->
foreign_db
->
str
,
fk
->
foreign_table
->
str
);
const
char
*
db
=
fk
->
foreign_db
->
str
;
const
char
*
table_name
=
fk
->
foreign_table
->
str
;
MDL_key
key
(
MDL_key
::
TABLE
,
db
,
table_name
);
TABLE_LIST
*
tl
=
find_fk_prelocked_table
(
prelocking_ctx
,
key
,
lock_type
);
if
(
tl
==
NULL
)
TABLE_LIST
*
tl
=
NULL
;
bool
success
=
prelocking_ctx
->
fk_table_hash
.
insert
(
key
,
[
db
,
table_name
,
lock_type
](
const
TABLE_LIST
*
tl
)
{
return
tl
->
lock_type
>=
lock_type
&&
strcmp
(
tl
->
table_name
.
str
,
table_name
)
==
0
&&
strcmp
(
tl
->
db
.
str
,
db
)
==
0
;
},
[
&
tl
,
thd
]()
{
tl
=
(
TABLE_LIST
*
)
thd
->
alloc
(
sizeof
(
TABLE_LIST
));
return
tl
;
}
);
if
(
unlikely
(
!
success
))
{
tl
=
(
TABLE_LIST
*
)
thd
->
alloc
(
sizeof
(
TABLE_LIST
));
tl
->
init_one_table_for_prelocking
(
fk
->
foreign_db
,
fk
->
foreign_table
,
NULL
,
lock_type
,
TABLE_LIST
::
PRELOCK_FK
,
table_list
->
belong_to_view
,
op
,
&
prelocking_ctx
->
query_tables_last
,
&
key
,
table_list
->
for_insert_data
);
bool
success
=
prelocking_ctx
->
fk_table_hash
.
insert
(
tl
);
if
(
!
success
)
{
my_error
(
ER_OUTOFMEMORY
,
MYF
(
0
));
if
(
arena
)
thd
->
restore_active_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
TRUE
);
}
my_error
(
ER_OUTOFMEMORY
,
MYF
(
0
));
if
(
arena
)
thd
->
restore_active_arena
(
arena
,
&
backup
);
DBUG_RETURN
(
TRUE
);
}
if
(
tl
!=
NULL
)
{
tl
->
init_one_table_for_prelocking
(
fk
->
foreign_db
,
fk
->
foreign_table
,
NULL
,
lock_type
,
TABLE_LIST
::
PRELOCK_FK
,
table_list
->
belong_to_view
,
op
,
&
prelocking_ctx
->
query_tables_last
,
&
key
,
table_list
->
for_insert_data
);
}
}
if
(
arena
)
thd
->
restore_active_arena
(
arena
,
&
backup
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment