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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
10a8adc1
Commit
10a8adc1
authored
Jun 30, 2003
by
igor@rurik.mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Many files:
Added multiple key cache
parent
4c7714b7
Changes
22
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
573 additions
and
466 deletions
+573
-466
include/my_sys.h
include/my_sys.h
+14
-7
isam/_locking.c
isam/_locking.c
+2
-2
isam/_page.c
isam/_page.c
+13
-9
isam/close.c
isam/close.c
+2
-1
isam/isamchk.c
isam/isamchk.c
+6
-5
isam/panic.c
isam/panic.c
+1
-1
isam/test2.c
isam/test2.c
+2
-2
isam/test3.c
isam/test3.c
+1
-1
myisam/mi_check.c
myisam/mi_check.c
+13
-10
myisam/mi_close.c
myisam/mi_close.c
+1
-1
myisam/mi_delete_all.c
myisam/mi_delete_all.c
+1
-1
myisam/mi_extra.c
myisam/mi_extra.c
+2
-2
myisam/mi_locking.c
myisam/mi_locking.c
+3
-2
myisam/mi_page.c
myisam/mi_page.c
+8
-4
myisam/mi_panic.c
myisam/mi_panic.c
+1
-1
myisam/mi_preload.c
myisam/mi_preload.c
+5
-3
myisam/mi_test1.c
myisam/mi_test1.c
+1
-1
myisam/mi_test2.c
myisam/mi_test2.c
+7
-4
myisam/mi_test3.c
myisam/mi_test3.c
+1
-1
myisam/myisamchk.c
myisam/myisamchk.c
+3
-2
myisam/myisamlog.c
myisam/myisamlog.c
+3
-3
mysys/mf_keycache.c
mysys/mf_keycache.c
+483
-403
No files found.
include/my_sys.h
View file @
10a8adc1
...
@@ -248,6 +248,8 @@ extern my_bool NEAR my_disable_locking,NEAR my_disable_async_io,
...
@@ -248,6 +248,8 @@ extern my_bool NEAR my_disable_locking,NEAR my_disable_async_io,
extern
char
wild_many
,
wild_one
,
wild_prefix
;
extern
char
wild_many
,
wild_one
,
wild_prefix
;
extern
const
char
*
charsets_dir
;
extern
const
char
*
charsets_dir
;
extern
char
*
defaults_extra_file
;
extern
char
*
defaults_extra_file
;
extern
void
*
dflt_keycache
;
#define dflt_key_block_size DEFAULT_KEYCACHE_BLOCK_SIZE
typedef
struct
wild_file_pack
/* Struct to hold info when selecting files */
typedef
struct
wild_file_pack
/* Struct to hold info when selecting files */
{
{
...
@@ -639,16 +641,21 @@ extern int flush_write_cache(RECORD_CACHE *info);
...
@@ -639,16 +641,21 @@ extern int flush_write_cache(RECORD_CACHE *info);
extern
long
my_clock
(
void
);
extern
long
my_clock
(
void
);
extern
sig_handler
sigtstp_handler
(
int
signal_number
);
extern
sig_handler
sigtstp_handler
(
int
signal_number
);
extern
void
handle_recived_signals
(
void
);
extern
void
handle_recived_signals
(
void
);
extern
int
init_key_cache
(
ulong
use_mem
);
extern
int
init_key_cache
(
void
**
pkeycache
,
uint
key_cache_block_size
,
extern
int
resize_key_cache
(
ulong
use_mem
);
ulong
use_mem
);
extern
byte
*
key_cache_read
(
File
file
,
my_off_t
filepos
,
byte
*
buff
,
uint
length
,
extern
int
resize_key_cache
(
void
**
pkeycache
,
ulong
use_mem
);
extern
byte
*
key_cache_read
(
void
*
pkeycache
,
File
file
,
my_off_t
filepos
,
byte
*
buff
,
uint
length
,
uint
block_length
,
int
return_buffer
);
uint
block_length
,
int
return_buffer
);
extern
int
key_cache_insert
(
File
file
,
my_off_t
filepos
,
extern
int
key_cache_insert
(
void
*
pkeycache
,
File
file
,
my_off_t
filepos
,
byte
*
buff
,
uint
length
);
byte
*
buff
,
uint
length
);
extern
int
key_cache_write
(
File
file
,
my_off_t
filepos
,
byte
*
buff
,
uint
length
,
extern
int
key_cache_write
(
void
*
pkeycache
,
File
file
,
my_off_t
filepos
,
byte
*
buff
,
uint
length
,
uint
block_length
,
int
force_write
);
uint
block_length
,
int
force_write
);
extern
int
flush_key_blocks
(
int
file
,
enum
flush_type
type
);
extern
int
flush_key_blocks
(
void
*
pkeycache
,
extern
void
end_key_cache
(
void
);
int
file
,
enum
flush_type
type
);
extern
void
end_key_cache
(
void
**
pkeycache
,
my_bool
cleanup
);
extern
sig_handler
my_set_alarm_variable
(
int
signo
);
extern
sig_handler
my_set_alarm_variable
(
int
signo
);
extern
void
my_string_ptr_sort
(
void
*
base
,
uint
items
,
size_s
size
);
extern
void
my_string_ptr_sort
(
void
*
base
,
uint
items
,
size_s
size
);
extern
void
radixsort_for_str_ptr
(
uchar
*
base
[],
uint
number_of_elements
,
extern
void
radixsort_for_str_ptr
(
uchar
*
base
[],
uint
number_of_elements
,
...
...
isam/_locking.c
View file @
10a8adc1
...
@@ -50,7 +50,7 @@ int nisam_lock_database(N_INFO *info, int lock_type)
...
@@ -50,7 +50,7 @@ int nisam_lock_database(N_INFO *info, int lock_type)
else
else
count
=
--
share
->
w_locks
;
count
=
--
share
->
w_locks
;
if
(
info
->
lock_type
==
F_WRLCK
&&
!
share
->
w_locks
&&
if
(
info
->
lock_type
==
F_WRLCK
&&
!
share
->
w_locks
&&
flush_key_blocks
(
share
->
kfile
,
FLUSH_KEEP
))
flush_key_blocks
(
dflt_keycache
,
share
->
kfile
,
FLUSH_KEEP
))
error
=
my_errno
;
error
=
my_errno
;
if
(
info
->
opt_flag
&
(
READ_CACHE_USED
|
WRITE_CACHE_USED
))
if
(
info
->
opt_flag
&
(
READ_CACHE_USED
|
WRITE_CACHE_USED
))
if
(
end_io_cache
(
&
info
->
rec_cache
))
if
(
end_io_cache
(
&
info
->
rec_cache
))
...
@@ -329,7 +329,7 @@ int _nisam_test_if_changed(register N_INFO *info)
...
@@ -329,7 +329,7 @@ int _nisam_test_if_changed(register N_INFO *info)
share
->
state
.
uniq
!=
info
->
last_uniq
)
share
->
state
.
uniq
!=
info
->
last_uniq
)
{
/* Keyfile has changed */
{
/* Keyfile has changed */
if
(
share
->
state
.
process
!=
share
->
this_process
)
if
(
share
->
state
.
process
!=
share
->
this_process
)
VOID
(
flush_key_blocks
(
share
->
kfile
,
FLUSH_RELEASE
));
VOID
(
flush_key_blocks
(
dflt_keycache
,
share
->
kfile
,
FLUSH_RELEASE
));
share
->
last_process
=
share
->
state
.
process
;
share
->
last_process
=
share
->
state
.
process
;
info
->
last_loop
=
share
->
state
.
loop
;
info
->
last_loop
=
share
->
state
.
loop
;
info
->
last_uniq
=
share
->
state
.
uniq
;
info
->
last_uniq
=
share
->
state
.
uniq
;
...
...
isam/_page.c
View file @
10a8adc1
...
@@ -27,10 +27,11 @@ uchar *_nisam_fetch_keypage(register N_INFO *info, N_KEYDEF *keyinfo,
...
@@ -27,10 +27,11 @@ uchar *_nisam_fetch_keypage(register N_INFO *info, N_KEYDEF *keyinfo,
my_off_t
page
,
uchar
*
buff
,
int
return_buffer
)
my_off_t
page
,
uchar
*
buff
,
int
return_buffer
)
{
{
uchar
*
tmp
;
uchar
*
tmp
;
tmp
=
(
uchar
*
)
key_cache_read
(
info
->
s
->
kfile
,
page
,(
byte
*
)
buff
,
tmp
=
(
uchar
*
)
key_cache_read
(
dflt_keycache
,
(
uint
)
keyinfo
->
base
.
block_length
,
info
->
s
->
kfile
,
page
,(
byte
*
)
buff
,
(
uint
)
keyinfo
->
base
.
block_length
,
(
uint
)
keyinfo
->
base
.
block_length
,
return_buffer
);
(
uint
)
keyinfo
->
base
.
block_length
,
return_buffer
);
if
(
tmp
==
info
->
buff
)
if
(
tmp
==
info
->
buff
)
{
{
info
->
update
|=
HA_STATE_BUFF_SAVED
;
info
->
update
|=
HA_STATE_BUFF_SAVED
;
...
@@ -83,9 +84,10 @@ int _nisam_write_keypage(register N_INFO *info, register N_KEYDEF *keyinfo,
...
@@ -83,9 +84,10 @@ int _nisam_write_keypage(register N_INFO *info, register N_KEYDEF *keyinfo,
length
=
keyinfo
->
base
.
block_length
;
length
=
keyinfo
->
base
.
block_length
;
}
}
#endif
#endif
return
(
key_cache_write
(
info
->
s
->
kfile
,
page
,(
byte
*
)
buff
,
length
,
return
(
key_cache_write
(
dflt_keycache
,
(
uint
)
keyinfo
->
base
.
block_length
,
info
->
s
->
kfile
,
page
,(
byte
*
)
buff
,
length
,
(
int
)
(
info
->
lock_type
!=
F_UNLCK
)));
(
uint
)
keyinfo
->
base
.
block_length
,
(
int
)
(
info
->
lock_type
!=
F_UNLCK
)));
}
/* nisam_write_keypage */
}
/* nisam_write_keypage */
...
@@ -99,7 +101,8 @@ int _nisam_dispose(register N_INFO *info, N_KEYDEF *keyinfo, my_off_t pos)
...
@@ -99,7 +101,8 @@ int _nisam_dispose(register N_INFO *info, N_KEYDEF *keyinfo, my_off_t pos)
old_link
=
info
->
s
->
state
.
key_del
[
keynr
];
old_link
=
info
->
s
->
state
.
key_del
[
keynr
];
info
->
s
->
state
.
key_del
[
keynr
]
=
(
ulong
)
pos
;
info
->
s
->
state
.
key_del
[
keynr
]
=
(
ulong
)
pos
;
DBUG_RETURN
(
key_cache_write
(
info
->
s
->
kfile
,
pos
,(
byte
*
)
&
old_link
,
DBUG_RETURN
(
key_cache_write
(
dflt_keycache
,
info
->
s
->
kfile
,
pos
,(
byte
*
)
&
old_link
,
sizeof
(
long
),
sizeof
(
long
),
(
uint
)
keyinfo
->
base
.
block_length
,
(
uint
)
keyinfo
->
base
.
block_length
,
(
int
)
(
info
->
lock_type
!=
F_UNLCK
)));
(
int
)
(
info
->
lock_type
!=
F_UNLCK
)));
...
@@ -126,7 +129,8 @@ ulong _nisam_new(register N_INFO *info, N_KEYDEF *keyinfo)
...
@@ -126,7 +129,8 @@ ulong _nisam_new(register N_INFO *info, N_KEYDEF *keyinfo)
}
}
else
else
{
{
if
(
!
key_cache_read
(
info
->
s
->
kfile
,
pos
,
if
(
!
key_cache_read
(
dflt_keycache
,
info
->
s
->
kfile
,
pos
,
(
byte
*
)
&
info
->
s
->
state
.
key_del
[
keynr
],
(
byte
*
)
&
info
->
s
->
state
.
key_del
[
keynr
],
(
uint
)
sizeof
(
long
),
(
uint
)
sizeof
(
long
),
(
uint
)
keyinfo
->
base
.
block_length
,
0
))
(
uint
)
keyinfo
->
base
.
block_length
,
0
))
...
...
isam/close.c
View file @
10a8adc1
...
@@ -56,7 +56,8 @@ int nisam_close(register N_INFO *info)
...
@@ -56,7 +56,8 @@ int nisam_close(register N_INFO *info)
if
(
flag
)
if
(
flag
)
{
{
if
(
share
->
kfile
>=
0
&&
flush_key_blocks
(
share
->
kfile
,
FLUSH_RELEASE
))
if
(
share
->
kfile
>=
0
&&
flush_key_blocks
(
dflt_keycache
,
share
->
kfile
,
FLUSH_RELEASE
))
error
=
my_errno
;
error
=
my_errno
;
if
(
share
->
kfile
>=
0
&&
my_close
(
share
->
kfile
,
MYF
(
0
)))
if
(
share
->
kfile
>=
0
&&
my_close
(
share
->
kfile
,
MYF
(
0
)))
error
=
my_errno
;
error
=
my_errno
;
...
...
isam/isamchk.c
View file @
10a8adc1
...
@@ -516,7 +516,8 @@ static int nisamchk(my_string filename)
...
@@ -516,7 +516,8 @@ static int nisamchk(my_string filename)
if
(
!
rep_quick
)
if
(
!
rep_quick
)
{
{
if
(
testflag
&
T_EXTEND
)
if
(
testflag
&
T_EXTEND
)
VOID
(
init_key_cache
(
use_buffers
));
VOID
(
init_key_cache
(
&
dflt_keycache
,
dflt_key_block_size
,
use_buffers
));
VOID
(
init_io_cache
(
&
read_cache
,
datafile
,(
uint
)
read_buffer_length
,
VOID
(
init_io_cache
(
&
read_cache
,
datafile
,(
uint
)
read_buffer_length
,
READ_CACHE
,
share
->
pack
.
header_length
,
1
,
READ_CACHE
,
share
->
pack
.
header_length
,
1
,
MYF
(
MY_WME
)));
MYF
(
MY_WME
)));
...
@@ -1459,7 +1460,7 @@ my_string name;
...
@@ -1459,7 +1460,7 @@ my_string name;
printf
(
"Data records: %lu
\n
"
,(
ulong
)
share
->
state
.
records
);
printf
(
"Data records: %lu
\n
"
,(
ulong
)
share
->
state
.
records
);
}
}
VOID
(
init_key_cache
(
use_buffers
));
VOID
(
init_key_cache
(
&
dflt_keycache
,
dflt_key_block_size
,
use_buffers
));
if
(
init_io_cache
(
&
read_cache
,
info
->
dfile
,(
uint
)
read_buffer_length
,
if
(
init_io_cache
(
&
read_cache
,
info
->
dfile
,(
uint
)
read_buffer_length
,
READ_CACHE
,
share
->
pack
.
header_length
,
1
,
MYF
(
MY_WME
)))
READ_CACHE
,
share
->
pack
.
header_length
,
1
,
MYF
(
MY_WME
)))
goto
err
;
goto
err
;
...
@@ -1887,12 +1888,12 @@ static void lock_memory(void)
...
@@ -1887,12 +1888,12 @@ static void lock_memory(void)
static
int
flush_blocks
(
file
)
static
int
flush_blocks
(
file
)
File
file
;
File
file
;
{
{
if
(
flush_key_blocks
(
file
,
FLUSH_RELEASE
))
if
(
flush_key_blocks
(
dflt_keycache
,
file
,
FLUSH_RELEASE
))
{
{
print_error
(
"%d when trying to write bufferts"
,
my_errno
);
print_error
(
"%d when trying to write bufferts"
,
my_errno
);
return
(
1
);
return
(
1
);
}
}
end_key_cache
();
end_key_cache
(
&
dflt_keycache
,
1
);
return
0
;
return
0
;
}
/* flush_blocks */
}
/* flush_blocks */
...
@@ -1936,7 +1937,7 @@ int write_info;
...
@@ -1936,7 +1937,7 @@ int write_info;
if
(
share
->
state
.
key_root
[
sort_key
]
==
NI_POS_ERROR
)
if
(
share
->
state
.
key_root
[
sort_key
]
==
NI_POS_ERROR
)
DBUG_RETURN
(
0
);
/* Nothing to do */
DBUG_RETURN
(
0
);
/* Nothing to do */
init_key_cache
(
use_buffers
);
init_key_cache
(
&
dflt_keycache
,
dflt_key_block_size
,
use_buffers
);
if
(
init_io_cache
(
&
info
->
rec_cache
,
-
1
,(
uint
)
write_buffer_length
,
if
(
init_io_cache
(
&
info
->
rec_cache
,
-
1
,(
uint
)
write_buffer_length
,
WRITE_CACHE
,
share
->
pack
.
header_length
,
1
,
WRITE_CACHE
,
share
->
pack
.
header_length
,
1
,
MYF
(
MY_WME
|
MY_WAIT_IF_FULL
)))
MYF
(
MY_WME
|
MY_WAIT_IF_FULL
)))
...
...
isam/panic.c
View file @
10a8adc1
...
@@ -48,7 +48,7 @@ int nisam_panic(enum ha_panic_function flag)
...
@@ -48,7 +48,7 @@ int nisam_panic(enum ha_panic_function flag)
if
(
info
->
s
->
base
.
options
&
HA_OPTION_READ_ONLY_DATA
)
if
(
info
->
s
->
base
.
options
&
HA_OPTION_READ_ONLY_DATA
)
break
;
break
;
#endif
#endif
if
(
flush_key_blocks
(
info
->
s
->
kfile
,
FLUSH_RELEASE
))
if
(
flush_key_blocks
(
dflt_keycache
,
info
->
s
->
kfile
,
FLUSH_RELEASE
))
error
=
my_errno
;
error
=
my_errno
;
if
(
info
->
opt_flag
&
WRITE_CACHE_USED
)
if
(
info
->
opt_flag
&
WRITE_CACHE_USED
)
if
(
flush_io_cache
(
&
info
->
rec_cache
))
if
(
flush_io_cache
(
&
info
->
rec_cache
))
...
...
isam/test2.c
View file @
10a8adc1
...
@@ -156,7 +156,7 @@ int main(int argc, char *argv[])
...
@@ -156,7 +156,7 @@ int main(int argc, char *argv[])
goto
err
;
goto
err
;
printf
(
"- Writing key:s
\n
"
);
printf
(
"- Writing key:s
\n
"
);
if
(
key_cacheing
)
if
(
key_cacheing
)
init_key_cache
(
IO_SIZE
*
16
);
/* Use a small cache */
init_key_cache
(
&
dflt_keycache
,
dflt_key_block_size
,
IO_SIZE
*
16
);
/* Use a small cache */
if
(
locking
)
if
(
locking
)
nisam_lock_database
(
file
,
F_WRLCK
);
nisam_lock_database
(
file
,
F_WRLCK
);
if
(
write_cacheing
)
if
(
write_cacheing
)
...
@@ -674,7 +674,7 @@ end:
...
@@ -674,7 +674,7 @@ end:
puts
(
"Locking used"
);
puts
(
"Locking used"
);
if
(
use_blob
)
if
(
use_blob
)
puts
(
"blobs used"
);
puts
(
"blobs used"
);
end_key_cache
();
end_key_cache
(
&
dflt_keycache
,
1
);
if
(
blob_buffer
)
if
(
blob_buffer
)
my_free
(
blob_buffer
,
MYF
(
0
));
my_free
(
blob_buffer
,
MYF
(
0
));
my_end
(
MY_CHECK_ERROR
|
MY_GIVE_INFO
);
my_end
(
MY_CHECK_ERROR
|
MY_GIVE_INFO
);
...
...
isam/test3.c
View file @
10a8adc1
...
@@ -173,7 +173,7 @@ void start_test(int id)
...
@@ -173,7 +173,7 @@ void start_test(int id)
exit
(
1
);
exit
(
1
);
}
}
if
(
key_cacheing
&&
rnd
(
2
)
==
0
)
if
(
key_cacheing
&&
rnd
(
2
)
==
0
)
init_key_cache
(
65536L
);
init_key_cache
(
&
dflt_keycache
,
dflt_key_block_size
,
65536L
);
printf
(
"Process %d, pid: %d
\n
"
,
id
,(
int
)
getpid
());
fflush
(
stdout
);
printf
(
"Process %d, pid: %d
\n
"
,
id
,(
int
)
getpid
());
fflush
(
stdout
);
for
(
error
=
i
=
0
;
i
<
tests
&&
!
error
;
i
++
)
for
(
error
=
i
=
0
;
i
<
tests
&&
!
error
;
i
++
)
...
...
myisam/mi_check.c
View file @
10a8adc1
...
@@ -230,7 +230,8 @@ static int check_k_link(MI_CHECK *param, register MI_INFO *info, uint nr)
...
@@ -230,7 +230,8 @@ static int check_k_link(MI_CHECK *param, register MI_INFO *info, uint nr)
if
(
next_link
>
info
->
state
->
key_file_length
||
if
(
next_link
>
info
->
state
->
key_file_length
||
next_link
&
(
info
->
s
->
blocksize
-
1
))
next_link
&
(
info
->
s
->
blocksize
-
1
))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
if
(
!
(
buff
=
key_cache_read
(
info
->
s
->
kfile
,
next_link
,
(
byte
*
)
info
->
buff
,
if
(
!
(
buff
=
key_cache_read
(
dflt_keycache
,
info
->
s
->
kfile
,
next_link
,
(
byte
*
)
info
->
buff
,
myisam_block_size
,
block_size
,
1
)))
myisam_block_size
,
block_size
,
1
)))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
next_link
=
mi_sizekorr
(
buff
);
next_link
=
mi_sizekorr
(
buff
);
...
@@ -259,7 +260,8 @@ int chk_size(MI_CHECK *param, register MI_INFO *info)
...
@@ -259,7 +260,8 @@ int chk_size(MI_CHECK *param, register MI_INFO *info)
if
(
!
(
param
->
testflag
&
T_SILENT
))
puts
(
"- check file-size"
);
if
(
!
(
param
->
testflag
&
T_SILENT
))
puts
(
"- check file-size"
);
flush_key_blocks
(
info
->
s
->
kfile
,
FLUSH_FORCE_WRITE
);
/* If called externally */
flush_key_blocks
(
dflt_keycache
,
info
->
s
->
kfile
,
FLUSH_FORCE_WRITE
);
/* If called externally */
size
=
my_seek
(
info
->
s
->
kfile
,
0L
,
MY_SEEK_END
,
MYF
(
0
));
size
=
my_seek
(
info
->
s
->
kfile
,
0L
,
MY_SEEK_END
,
MYF
(
0
));
if
((
skr
=
(
my_off_t
)
info
->
state
->
key_file_length
)
!=
size
)
if
((
skr
=
(
my_off_t
)
info
->
state
->
key_file_length
)
!=
size
)
...
@@ -1119,7 +1121,8 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
...
@@ -1119,7 +1121,8 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
param
->
testflag
|=
T_REP
;
/* for easy checking */
param
->
testflag
|=
T_REP
;
/* for easy checking */
if
(
!
param
->
using_global_keycache
)
if
(
!
param
->
using_global_keycache
)
VOID
(
init_key_cache
(
param
->
use_buffers
));
VOID
(
init_key_cache
(
&
dflt_keycache
,
dflt_key_block_size
,
param
->
use_buffers
));
if
(
init_io_cache
(
&
param
->
read_cache
,
info
->
dfile
,
if
(
init_io_cache
(
&
param
->
read_cache
,
info
->
dfile
,
(
uint
)
param
->
read_buffer_length
,
(
uint
)
param
->
read_buffer_length
,
...
@@ -1477,13 +1480,13 @@ void lock_memory(MI_CHECK *param __attribute__((unused)))
...
@@ -1477,13 +1480,13 @@ void lock_memory(MI_CHECK *param __attribute__((unused)))
int
flush_blocks
(
MI_CHECK
*
param
,
File
file
)
int
flush_blocks
(
MI_CHECK
*
param
,
File
file
)
{
{
if
(
flush_key_blocks
(
file
,
FLUSH_RELEASE
))
if
(
flush_key_blocks
(
dflt_keycache
,
file
,
FLUSH_RELEASE
))
{
{
mi_check_print_error
(
param
,
"%d when trying to write bufferts"
,
my_errno
);
mi_check_print_error
(
param
,
"%d when trying to write bufferts"
,
my_errno
);
return
(
1
);
return
(
1
);
}
}
if
(
!
param
->
using_global_keycache
)
if
(
!
param
->
using_global_keycache
)
end_key_cache
();
end_key_cache
(
&
dflt_keycache
,
1
);
return
0
;
return
0
;
}
/* flush_blocks */
}
/* flush_blocks */
...
@@ -1537,7 +1540,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
...
@@ -1537,7 +1540,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
}
}
/* Flush key cache for this file if we are calling this outside myisamchk */
/* Flush key cache for this file if we are calling this outside myisamchk */
flush_key_blocks
(
share
->
kfile
,
FLUSH_IGNORE_CHANGED
);
flush_key_blocks
(
dflt_keycache
,
share
->
kfile
,
FLUSH_IGNORE_CHANGED
);
share
->
state
.
version
=
(
ulong
)
time
((
time_t
*
)
0
);
share
->
state
.
version
=
(
ulong
)
time
((
time_t
*
)
0
);
old_state
=
share
->
state
;
/* save state if not stored */
old_state
=
share
->
state
;
/* save state if not stored */
...
@@ -1843,7 +1846,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
...
@@ -1843,7 +1846,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
Flush key cache for this file if we are calling this outside
Flush key cache for this file if we are calling this outside
myisamchk
myisamchk
*/
*/
flush_key_blocks
(
share
->
kfile
,
FLUSH_IGNORE_CHANGED
);
flush_key_blocks
(
dflt_keycache
,
share
->
kfile
,
FLUSH_IGNORE_CHANGED
);
/* Clear the pointers to the given rows */
/* Clear the pointers to the given rows */
for
(
i
=
0
;
i
<
share
->
base
.
keys
;
i
++
)
for
(
i
=
0
;
i
<
share
->
base
.
keys
;
i
++
)
share
->
state
.
key_root
[
i
]
=
HA_OFFSET_ERROR
;
share
->
state
.
key_root
[
i
]
=
HA_OFFSET_ERROR
;
...
@@ -1853,7 +1856,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
...
@@ -1853,7 +1856,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
}
}
else
else
{
{
if
(
flush_key_blocks
(
share
->
kfile
,
FLUSH_FORCE_WRITE
))
if
(
flush_key_blocks
(
dflt_keycache
,
share
->
kfile
,
FLUSH_FORCE_WRITE
))
goto
err
;
goto
err
;
key_map
=
~
key_map
;
/* Create the missing keys */
key_map
=
~
key_map
;
/* Create the missing keys */
}
}
...
@@ -2206,7 +2209,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
...
@@ -2206,7 +2209,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
Flush key cache for this file if we are calling this outside
Flush key cache for this file if we are calling this outside
myisamchk
myisamchk
*/
*/
flush_key_blocks
(
share
->
kfile
,
FLUSH_IGNORE_CHANGED
);
flush_key_blocks
(
dflt_keycache
,
share
->
kfile
,
FLUSH_IGNORE_CHANGED
);
/* Clear the pointers to the given rows */
/* Clear the pointers to the given rows */
for
(
i
=
0
;
i
<
share
->
base
.
keys
;
i
++
)
for
(
i
=
0
;
i
<
share
->
base
.
keys
;
i
++
)
share
->
state
.
key_root
[
i
]
=
HA_OFFSET_ERROR
;
share
->
state
.
key_root
[
i
]
=
HA_OFFSET_ERROR
;
...
@@ -2216,7 +2219,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
...
@@ -2216,7 +2219,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
}
}
else
else
{
{
if
(
flush_key_blocks
(
share
->
kfile
,
FLUSH_FORCE_WRITE
))
if
(
flush_key_blocks
(
dflt_keycache
,
share
->
kfile
,
FLUSH_FORCE_WRITE
))
goto
err
;
goto
err
;
key_map
=
~
key_map
;
/* Create the missing keys */
key_map
=
~
key_map
;
/* Create the missing keys */
}
}
...
...
myisam/mi_close.c
View file @
10a8adc1
...
@@ -64,7 +64,7 @@ int mi_close(register MI_INFO *info)
...
@@ -64,7 +64,7 @@ int mi_close(register MI_INFO *info)
if
(
flag
)
if
(
flag
)
{
{
if
(
share
->
kfile
>=
0
&&
if
(
share
->
kfile
>=
0
&&
flush_key_blocks
(
share
->
kfile
,
flush_key_blocks
(
dflt_keycache
,
share
->
kfile
,
share
->
temporary
?
FLUSH_IGNORE_CHANGED
:
share
->
temporary
?
FLUSH_IGNORE_CHANGED
:
FLUSH_RELEASE
))
FLUSH_RELEASE
))
error
=
my_errno
;
error
=
my_errno
;
...
...
myisam/mi_delete_all.c
View file @
10a8adc1
...
@@ -53,7 +53,7 @@ int mi_delete_all_rows(MI_INFO *info)
...
@@ -53,7 +53,7 @@ int mi_delete_all_rows(MI_INFO *info)
If we are using delayed keys or if the user has done changes to the tables
If we are using delayed keys or if the user has done changes to the tables
since it was locked then there may be key blocks in the key cache
since it was locked then there may be key blocks in the key cache
*/
*/
flush_key_blocks
(
share
->
kfile
,
FLUSH_IGNORE_CHANGED
);
flush_key_blocks
(
dflt_keycache
,
share
->
kfile
,
FLUSH_IGNORE_CHANGED
);
if
(
my_chsize
(
info
->
dfile
,
0
,
0
,
MYF
(
MY_WME
))
||
if
(
my_chsize
(
info
->
dfile
,
0
,
0
,
MYF
(
MY_WME
))
||
my_chsize
(
share
->
kfile
,
share
->
base
.
keystart
,
0
,
MYF
(
MY_WME
))
)
my_chsize
(
share
->
kfile
,
share
->
base
.
keystart
,
0
,
MYF
(
MY_WME
))
)
goto
err
;
goto
err
;
...
...
myisam/mi_extra.c
View file @
10a8adc1
...
@@ -279,7 +279,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
...
@@ -279,7 +279,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
#ifdef __WIN__
#ifdef __WIN__
/* Close the isam and data files as Win32 can't drop an open table */
/* Close the isam and data files as Win32 can't drop an open table */
pthread_mutex_lock
(
&
share
->
intern_lock
);
pthread_mutex_lock
(
&
share
->
intern_lock
);
if
(
flush_key_blocks
(
share
->
kfile
,
if
(
flush_key_blocks
(
dflt_keycache
,
share
->
kfile
,
(
function
==
HA_EXTRA_FORCE_REOPEN
?
(
function
==
HA_EXTRA_FORCE_REOPEN
?
FLUSH_RELEASE
:
FLUSH_IGNORE_CHANGED
)))
FLUSH_RELEASE
:
FLUSH_IGNORE_CHANGED
)))
{
{
...
@@ -325,7 +325,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
...
@@ -325,7 +325,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
break
;
break
;
case
HA_EXTRA_FLUSH
:
case
HA_EXTRA_FLUSH
:
if
(
!
share
->
temporary
)
if
(
!
share
->
temporary
)
flush_key_blocks
(
share
->
kfile
,
FLUSH_KEEP
);
flush_key_blocks
(
dflt_keycache
,
share
->
kfile
,
FLUSH_KEEP
);
#ifdef HAVE_PWRITE
#ifdef HAVE_PWRITE
_mi_decrement_open_count
(
info
);
_mi_decrement_open_count
(
info
);
#endif
#endif
...
...
myisam/mi_locking.c
View file @
10a8adc1
...
@@ -51,7 +51,8 @@ int mi_lock_database(MI_INFO *info, int lock_type)
...
@@ -51,7 +51,8 @@ int mi_lock_database(MI_INFO *info, int lock_type)
count
=
--
share
->
w_locks
;
count
=
--
share
->
w_locks
;
--
share
->
tot_locks
;
--
share
->
tot_locks
;
if
(
info
->
lock_type
==
F_WRLCK
&&
!
share
->
w_locks
&&
if
(
info
->
lock_type
==
F_WRLCK
&&
!
share
->
w_locks
&&
!
share
->
delay_key_write
&&
flush_key_blocks
(
share
->
kfile
,
FLUSH_KEEP
))
!
share
->
delay_key_write
&&
flush_key_blocks
(
dflt_keycache
,
share
->
kfile
,
FLUSH_KEEP
))
{
{
error
=
my_errno
;
error
=
my_errno
;
mi_mark_crashed
(
info
);
/* Mark that table must be checked */
mi_mark_crashed
(
info
);
/* Mark that table must be checked */
...
@@ -385,7 +386,7 @@ int _mi_test_if_changed(register MI_INFO *info)
...
@@ -385,7 +386,7 @@ int _mi_test_if_changed(register MI_INFO *info)
{
/* Keyfile has changed */
{
/* Keyfile has changed */
DBUG_PRINT
(
"info"
,(
"index file changed"
));
DBUG_PRINT
(
"info"
,(
"index file changed"
));
if
(
share
->
state
.
process
!=
share
->
this_process
)
if
(
share
->
state
.
process
!=
share
->
this_process
)
VOID
(
flush_key_blocks
(
share
->
kfile
,
FLUSH_RELEASE
));
VOID
(
flush_key_blocks
(
dflt_keycache
,
share
->
kfile
,
FLUSH_RELEASE
));
share
->
last_process
=
share
->
state
.
process
;
share
->
last_process
=
share
->
state
.
process
;
info
->
last_unique
=
share
->
state
.
unique
;
info
->
last_unique
=
share
->
state
.
unique
;
info
->
last_loop
=
share
->
state
.
update_count
;
info
->
last_loop
=
share
->
state
.
update_count
;
...
...
myisam/mi_page.c
View file @
10a8adc1
...
@@ -31,7 +31,8 @@ uchar *_mi_fetch_keypage(register MI_INFO *info, MI_KEYDEF *keyinfo,
...
@@ -31,7 +31,8 @@ uchar *_mi_fetch_keypage(register MI_INFO *info, MI_KEYDEF *keyinfo,
DBUG_ENTER
(
"_mi_fetch_keypage"
);
DBUG_ENTER
(
"_mi_fetch_keypage"
);
DBUG_PRINT
(
"enter"
,(
"page: %ld"
,
page
));
DBUG_PRINT
(
"enter"
,(
"page: %ld"
,
page
));
tmp
=
(
uchar
*
)
key_cache_read
(
info
->
s
->
kfile
,
page
,(
byte
*
)
buff
,
tmp
=
(
uchar
*
)
key_cache_read
(
dflt_keycache
,
info
->
s
->
kfile
,
page
,(
byte
*
)
buff
,
(
uint
)
keyinfo
->
block_length
,
(
uint
)
keyinfo
->
block_length
,
(
uint
)
keyinfo
->
block_length
,
(
uint
)
keyinfo
->
block_length
,
return_buffer
);
return_buffer
);
...
@@ -92,7 +93,8 @@ int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo,
...
@@ -92,7 +93,8 @@ int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo,
length
=
keyinfo
->
block_length
;
length
=
keyinfo
->
block_length
;
}
}
#endif
#endif
DBUG_RETURN
((
key_cache_write
(
info
->
s
->
kfile
,
page
,(
byte
*
)
buff
,
length
,
DBUG_RETURN
((
key_cache_write
(
dflt_keycache
,
info
->
s
->
kfile
,
page
,(
byte
*
)
buff
,
length
,
(
uint
)
keyinfo
->
block_length
,
(
uint
)
keyinfo
->
block_length
,
(
int
)
((
info
->
lock_type
!=
F_UNLCK
)
||
(
int
)
((
info
->
lock_type
!=
F_UNLCK
)
||
info
->
s
->
delay_key_write
))));
info
->
s
->
delay_key_write
))));
...
@@ -112,7 +114,8 @@ int _mi_dispose(register MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos)
...
@@ -112,7 +114,8 @@ int _mi_dispose(register MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos)
info
->
s
->
state
.
key_del
[
keyinfo
->
block_size
]
=
pos
;
info
->
s
->
state
.
key_del
[
keyinfo
->
block_size
]
=
pos
;
mi_sizestore
(
buff
,
old_link
);
mi_sizestore
(
buff
,
old_link
);
info
->
s
->
state
.
changed
|=
STATE_NOT_SORTED_PAGES
;
info
->
s
->
state
.
changed
|=
STATE_NOT_SORTED_PAGES
;
DBUG_RETURN
(
key_cache_write
(
info
->
s
->
kfile
,
pos
,
buff
,
DBUG_RETURN
(
key_cache_write
(
dflt_keycache
,
info
->
s
->
kfile
,
pos
,
buff
,
sizeof
(
buff
),
sizeof
(
buff
),
(
uint
)
keyinfo
->
block_length
,
(
uint
)
keyinfo
->
block_length
,
(
int
)
(
info
->
lock_type
!=
F_UNLCK
)));
(
int
)
(
info
->
lock_type
!=
F_UNLCK
)));
...
@@ -140,7 +143,8 @@ my_off_t _mi_new(register MI_INFO *info, MI_KEYDEF *keyinfo)
...
@@ -140,7 +143,8 @@ my_off_t _mi_new(register MI_INFO *info, MI_KEYDEF *keyinfo)
}
}
else
else
{
{
if
(
!
key_cache_read
(
info
->
s
->
kfile
,
pos
,
if
(
!
key_cache_read
(
dflt_keycache
,
info
->
s
->
kfile
,
pos
,
buff
,
buff
,
(
uint
)
sizeof
(
buff
),
(
uint
)
sizeof
(
buff
),
(
uint
)
keyinfo
->
block_length
,
0
))
(
uint
)
keyinfo
->
block_length
,
0
))
...
...
myisam/mi_panic.c
View file @
10a8adc1
...
@@ -48,7 +48,7 @@ int mi_panic(enum ha_panic_function flag)
...
@@ -48,7 +48,7 @@ int mi_panic(enum ha_panic_function flag)
if
(
info
->
s
->
options
&
HA_OPTION_READ_ONLY_DATA
)
if
(
info
->
s
->
options
&
HA_OPTION_READ_ONLY_DATA
)
break
;
break
;
#endif
#endif
if
(
flush_key_blocks
(
info
->
s
->
kfile
,
FLUSH_RELEASE
))
if
(
flush_key_blocks
(
dflt_keycache
,
info
->
s
->
kfile
,
FLUSH_RELEASE
))
error
=
my_errno
;
error
=
my_errno
;
if
(
info
->
opt_flag
&
WRITE_CACHE_USED
)
if
(
info
->
opt_flag
&
WRITE_CACHE_USED
)
if
(
flush_io_cache
(
&
info
->
rec_cache
))
if
(
flush_io_cache
(
&
info
->
rec_cache
))
...
...
myisam/mi_preload.c
View file @
10a8adc1
...
@@ -72,7 +72,7 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves)
...
@@ -72,7 +72,7 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves)
if
(
!
(
buff
=
(
uchar
*
)
my_malloc
(
length
,
MYF
(
MY_WME
))))
if
(
!
(
buff
=
(
uchar
*
)
my_malloc
(
length
,
MYF
(
MY_WME
))))
return
(
my_errno
=
HA_ERR_OUT_OF_MEM
);
return
(
my_errno
=
HA_ERR_OUT_OF_MEM
);
if
(
flush_key_blocks
(
share
->
kfile
,
FLUSH_RELEASE
))
if
(
flush_key_blocks
(
dflt_keycache
,
share
->
kfile
,
FLUSH_RELEASE
))
goto
err
;
goto
err
;
do
do
...
@@ -89,7 +89,8 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves)
...
@@ -89,7 +89,8 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves)
{
{
if
(
mi_test_if_nod
(
buff
))
if
(
mi_test_if_nod
(
buff
))
{
{
if
(
key_cache_insert
(
share
->
kfile
,
pos
,
(
byte
*
)
buff
,
block_length
))
if
(
key_cache_insert
(
dflt_keycache
,
share
->
kfile
,
pos
,
(
byte
*
)
buff
,
block_length
))
goto
err
;
goto
err
;
}
}
pos
+=
block_length
;
pos
+=
block_length
;
...
@@ -99,7 +100,8 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves)
...
@@ -99,7 +100,8 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves)
}
}
else
else
{
{
if
(
key_cache_insert
(
share
->
kfile
,
pos
,
(
byte
*
)
buff
,
length
))
if
(
key_cache_insert
(
dflt_keycache
,
share
->
kfile
,
pos
,
(
byte
*
)
buff
,
length
))
goto
err
;
goto
err
;
pos
+=
length
;
pos
+=
length
;
}
}
...
...
myisam/mi_test1.c
View file @
10a8adc1
...
@@ -50,7 +50,7 @@ int main(int argc,char *argv[])
...
@@ -50,7 +50,7 @@ int main(int argc,char *argv[])
MY_INIT
(
argv
[
0
]);
MY_INIT
(
argv
[
0
]);
my_init
();
my_init
();
if
(
key_cacheing
)
if
(
key_cacheing
)
init_key_cache
(
IO_SIZE
*
16
);
init_key_cache
(
&
dflt_keycache
,
dflt_key_block_size
,
IO_SIZE
*
16
);
get_options
(
argc
,
argv
);
get_options
(
argc
,
argv
);
exit
(
run_test
(
"test1"
));
exit
(
run_test
(
"test1"
));
...
...
myisam/mi_test2.c
View file @
10a8adc1
...
@@ -214,7 +214,7 @@ int main(int argc, char *argv[])
...
@@ -214,7 +214,7 @@ int main(int argc, char *argv[])
if
(
!
silent
)
if
(
!
silent
)
printf
(
"- Writing key:s
\n
"
);
printf
(
"- Writing key:s
\n
"
);
if
(
key_cacheing
)
if
(
key_cacheing
)
init_key_cache
(
key_cache_size
);
/* Use a small cache */
init_key_cache
(
&
dflt_keycache
,
dflt_key_block_size
,
key_cache_size
);
/* Use a small cache */
if
(
locking
)
if
(
locking
)
mi_lock_database
(
file
,
F_WRLCK
);
mi_lock_database
(
file
,
F_WRLCK
);
if
(
write_cacheing
)
if
(
write_cacheing
)
...
@@ -274,7 +274,7 @@ int main(int argc, char *argv[])
...
@@ -274,7 +274,7 @@ int main(int argc, char *argv[])
goto
end
;
goto
end
;
}
}
if
(
key_cacheing
)
if
(
key_cacheing
)
resize_key_cache
(
key_cache_size
*
2
);
resize_key_cache
(
&
dflt_keycache
,
key_cache_size
*
2
);
}
}
if
(
!
silent
)
if
(
!
silent
)
...
@@ -816,16 +816,19 @@ end:
...
@@ -816,16 +816,19 @@ end:
puts
(
"Locking used"
);
puts
(
"Locking used"
);
if
(
use_blob
)
if
(
use_blob
)
puts
(
"blobs used"
);
puts
(
"blobs used"
);
#if 0
printf("key cache status: \n\
printf("key cache status: \n\
blocks used:%10lu\n\
blocks used:%10lu\n\
w_requests: %10lu\n\
w_requests: %10lu\n\
writes: %10lu\n\
writes: %10lu\n\
r_requests: %10lu\n\
r_requests: %10lu\n\
reads: %10lu\n",
reads: %10lu\n",
my_blocks_used
,
my_cache_w_requests
,
my_cache_write
,
my_blocks_used,
my_cache_w_requests, my_cache_write,
my_cache_r_requests, my_cache_read);
my_cache_r_requests, my_cache_read);
#endif
}
}
end_key_cache
();
end_key_cache
(
&
dflt_keycache
,
1
);
if
(
blob_buffer
)
if
(
blob_buffer
)
my_free
(
blob_buffer
,
MYF
(
0
));
my_free
(
blob_buffer
,
MYF
(
0
));
my_end
(
silent
?
MY_CHECK_ERROR
:
MY_CHECK_ERROR
|
MY_GIVE_INFO
);
my_end
(
silent
?
MY_CHECK_ERROR
:
MY_CHECK_ERROR
|
MY_GIVE_INFO
);
...
...
myisam/mi_test3.c
View file @
10a8adc1
...
@@ -177,7 +177,7 @@ void start_test(int id)
...
@@ -177,7 +177,7 @@ void start_test(int id)
exit
(
1
);
exit
(
1
);
}
}
if
(
key_cacheing
&&
rnd
(
2
)
==
0
)
if
(
key_cacheing
&&
rnd
(
2
)
==
0
)
init_key_cache
(
65536L
);
init_key_cache
(
&
dflt_keycache
,
dflt_key_block_size
,
65536L
);
printf
(
"Process %d, pid: %d
\n
"
,
id
,
getpid
());
fflush
(
stdout
);
printf
(
"Process %d, pid: %d
\n
"
,
id
,
getpid
());
fflush
(
stdout
);
for
(
error
=
i
=
0
;
i
<
tests
&&
!
error
;
i
++
)
for
(
error
=
i
=
0
;
i
<
tests
&&
!
error
;
i
++
)
...
...
myisam/myisamchk.c
View file @
10a8adc1
...
@@ -1020,7 +1020,8 @@ static int myisamchk(MI_CHECK *param, my_string filename)
...
@@ -1020,7 +1020,8 @@ static int myisamchk(MI_CHECK *param, my_string filename)
!
(
param
->
testflag
&
(
T_FAST
|
T_FORCE_CREATE
)))
!
(
param
->
testflag
&
(
T_FAST
|
T_FORCE_CREATE
)))
{
{
if
(
param
->
testflag
&
(
T_EXTEND
|
T_MEDIUM
))
if
(
param
->
testflag
&
(
T_EXTEND
|
T_MEDIUM
))
VOID
(
init_key_cache
(
param
->
use_buffers
));
VOID
(
init_key_cache
(
&
dflt_keycache
,
dflt_key_block_size
,
param
->
use_buffers
));
VOID
(
init_io_cache
(
&
param
->
read_cache
,
datafile
,
VOID
(
init_io_cache
(
&
param
->
read_cache
,
datafile
,
(
uint
)
param
->
read_buffer_length
,
(
uint
)
param
->
read_buffer_length
,
READ_CACHE
,
READ_CACHE
,
...
@@ -1437,7 +1438,7 @@ static int mi_sort_records(MI_CHECK *param,
...
@@ -1437,7 +1438,7 @@ static int mi_sort_records(MI_CHECK *param,
if
(
share
->
state
.
key_root
[
sort_key
]
==
HA_OFFSET_ERROR
)
if
(
share
->
state
.
key_root
[
sort_key
]
==
HA_OFFSET_ERROR
)
DBUG_RETURN
(
0
);
/* Nothing to do */
DBUG_RETURN
(
0
);
/* Nothing to do */
init_key_cache
(
param
->
use_buffers
);
init_key_cache
(
&
dflt_keycache
,
dflt_key_block_size
,
param
->
use_buffers
);
if
(
init_io_cache
(
&
info
->
rec_cache
,
-
1
,(
uint
)
param
->
write_buffer_length
,
if
(
init_io_cache
(
&
info
->
rec_cache
,
-
1
,(
uint
)
param
->
write_buffer_length
,
WRITE_CACHE
,
share
->
pack
.
header_length
,
1
,
WRITE_CACHE
,
share
->
pack
.
header_length
,
1
,
MYF
(
MY_WME
|
MY_WAIT_IF_FULL
)))
MYF
(
MY_WME
|
MY_WAIT_IF_FULL
)))
...
...
myisam/myisamlog.c
View file @
10a8adc1
...
@@ -333,7 +333,7 @@ static int examine_log(my_string file_name, char **table_names)
...
@@ -333,7 +333,7 @@ static int examine_log(my_string file_name, char **table_names)
bzero
((
gptr
)
com_count
,
sizeof
(
com_count
));
bzero
((
gptr
)
com_count
,
sizeof
(
com_count
));
init_tree
(
&
tree
,
0
,
0
,
sizeof
(
file_info
),(
qsort_cmp2
)
file_info_compare
,
1
,
init_tree
(
&
tree
,
0
,
0
,
sizeof
(
file_info
),(
qsort_cmp2
)
file_info_compare
,
1
,
(
tree_element_free
)
file_info_free
,
NULL
);
(
tree_element_free
)
file_info_free
,
NULL
);
VOID
(
init_key_cache
(
KEY_CACHE_SIZE
));
VOID
(
init_key_cache
(
&
dflt_keycache
,
dflt_key_block_size
,
KEY_CACHE_SIZE
));
files_open
=
0
;
access_time
=
0
;
files_open
=
0
;
access_time
=
0
;
while
(
access_time
++
!=
number_of_commands
&&
while
(
access_time
++
!=
number_of_commands
&&
...
@@ -639,7 +639,7 @@ static int examine_log(my_string file_name, char **table_names)
...
@@ -639,7 +639,7 @@ static int examine_log(my_string file_name, char **table_names)
goto
end
;
goto
end
;
}
}
}
}
end_key_cache
();
end_key_cache
(
&
dflt_keycache
,
1
);
delete_tree
(
&
tree
);
delete_tree
(
&
tree
);
VOID
(
end_io_cache
(
&
cache
));
VOID
(
end_io_cache
(
&
cache
));
VOID
(
my_close
(
file
,
MYF
(
0
)));
VOID
(
my_close
(
file
,
MYF
(
0
)));
...
@@ -659,7 +659,7 @@ static int examine_log(my_string file_name, char **table_names)
...
@@ -659,7 +659,7 @@ static int examine_log(my_string file_name, char **table_names)
llstr
(
isamlog_filepos
,
llbuff
)));
llstr
(
isamlog_filepos
,
llbuff
)));
fflush
(
stderr
);
fflush
(
stderr
);
end:
end:
end_key_cache
();
end_key_cache
(
&
dflt_keycache
,
1
);
delete_tree
(
&
tree
);
delete_tree
(
&
tree
);
VOID
(
end_io_cache
(
&
cache
));
VOID
(
end_io_cache
(
&
cache
));
VOID
(
my_close
(
file
,
MYF
(
0
)));
VOID
(
my_close
(
file
,
MYF
(
0
)));
...
...
mysys/mf_keycache.c
View file @
10a8adc1
...
@@ -138,46 +138,54 @@ typedef struct st_block_link
...
@@ -138,46 +138,54 @@ typedef struct st_block_link
KEYCACHE_CONDVAR
*
condvar
;
/* condition variable for 'no readers' event */
KEYCACHE_CONDVAR
*
condvar
;
/* condition variable for 'no readers' event */
}
BLOCK_LINK
;
}
BLOCK_LINK
;
static
int
flush_all_key_blocks
()
;
void
*
dflt_keycache
;
static
void
test_key_cache
(
const
char
*
where
,
my_bool
lock
);
uint
key_cache_block_size
;
/* size of the page buffer of a cache block */
ulong
my_cache_w_requests
,
my_cache_write
,
/* counters */
uint
key_cache_block_size
=
/* size of the page buffer of a cache block
*/
my_cache_r_requests
,
my_cache_read
;
/* for statistics
*/
DEFAULT_KEYCACHE_BLOCK_SIZE
;
ulong
my_blocks_used
,
/* number of currently used blocks */
static
uint
key_cache_shift
;
my_blocks_changed
;
/* number of currently dirty blocks */
#define CHANGED_BLOCKS_HASH 128
/* must be power of 2 */
#define CHANGED_BLOCKS_HASH 128
/* must be power of 2 */
#define FLUSH_CACHE 2000
/* sort this many blocks at once */
#define FLUSH_CACHE 2000
/* sort this many blocks at once */
static
KEYCACHE_WQUEUE
typedef
struct
st_key_cache
waiting_for_hash_link
;
/* queue of requests waiting for a free hash link */
{
static
KEYCACHE_WQUEUE
my_bool
key_cache_inited
;
waiting_for_block
;
/* queue of requests waiting for a free block */
uint
key_cache_shift
;
uint
key_cache_block_size
;
/* size of the page buffer of a cache block */
static
HASH_LINK
**
my_hash_root
;
/* arr. of entries into hash table buckets */
uint
hash_entries
;
/* max number of entries in the hash table */
static
uint
my_hash_entries
;
/* max number of entries in the hash table */
int
hash_links
;
/* max number of hash links */
static
HASH_LINK
*
my_hash_link_root
;
/* memory for hash table links */
int
hash_links_used
;
/* number of hash links currently used */
static
int
my_hash_links
;
/* max number of hash links */
int
disk_blocks
;
/* max number of blocks in the cache */
static
int
my_hash_links_used
;
/* number of hash links currently used */
ulong
blocks_used
;
/* number of currently used blocks */
static
HASH_LINK
*
my_free_hash_list
;
/* list of free hash links */
ulong
blocks_changed
;
/* number of currently dirty blocks */
static
BLOCK_LINK
*
my_block_root
;
/* memory for block links */
ulong
cache_w_requests
;
static
int
my_disk_blocks
;
/* max number of blocks in the cache */
ulong
cache_write
;
static
byte
HUGE_PTR
*
my_block_mem
;
/* memory for block buffers */
ulong
cache_r_requests
;
static
BLOCK_LINK
*
my_used_last
;
/* ptr to the last block of the LRU chain */
ulong
cache_read
;
ulong
my_blocks_used
,
/* number of currently used blocks */
my_blocks_changed
;
/* number of currently dirty blocks */
#if defined(KEYCACHE_DEBUG)
#if defined(KEYCACHE_DEBUG)
static
ulong_blocks_available
;
/* number of blocks available in the LRU chain */
ulong
my_blocks_available
;
/* number of blocks available in the LRU chain */
#endif
#endif
/* defined(KEYCACHE_DEBUG) */
HASH_LINK
**
hash_root
;
/* arr. of entries into hash table buckets */
ulong
my_cache_w_requests
,
my_cache_write
,
/* counters */
HASH_LINK
*
hash_link_root
;
/* memory for hash table links */
my_cache_r_requests
,
my_cache_read
;
/* for statistics */
HASH_LINK
*
free_hash_list
;
/* list of free hash links */
static
BLOCK_LINK
BLOCK_LINK
*
block_root
;
/* memory for block links */
*
changed_blocks
[
CHANGED_BLOCKS_HASH
];
/* hash table for file dirty blocks */
byte
HUGE_PTR
*
block_mem
;
/* memory for block buffers */
static
BLOCK_LINK
BLOCK_LINK
*
used_last
;
/* ptr to the last block of the LRU chain */
*
file_blocks
[
CHANGED_BLOCKS_HASH
];
/* hash table for other file blocks */
pthread_mutex_t
thr_lock_keycache
;
/* that are not free */
KEYCACHE_WQUEUE
waiting_for_hash_link
;
/* waiting for a free hash link */
KEYCACHE_WQUEUE
waiting_for_block
;
/* requests waiting for a free block */
BLOCK_LINK
*
changed_blocks
[
CHANGED_BLOCKS_HASH
];
/* hash for dirty file bl.*/
BLOCK_LINK
*
file_blocks
[
CHANGED_BLOCKS_HASH
];
/* hash for other file bl.*/
}
KEY_CACHE
;
static
int
flush_all_key_blocks
();
static
void
test_key_cache
(
KEY_CACHE
*
keycache
,
const
char
*
where
,
my_bool
lock
);
#define KEYCACHE_HASH(f, pos) \
#define KEYCACHE_HASH(f, pos) \
(((ulong) ((pos) >> key_cache_shift)+(ulong) (f)) & (my_hash_entries-1))
(((ulong) ((pos) >> keycache->key_cache_shift)+ \
(ulong) (f)) & (keycache->hash_entries-1))
#define FILE_HASH(f) ((uint) (f) & (CHANGED_BLOCKS_HASH-1))
#define FILE_HASH(f) ((uint) (f) & (CHANGED_BLOCKS_HASH-1))
#define DEFAULT_KEYCACHE_DEBUG_LOG "keycache_debug.log"
#define DEFAULT_KEYCACHE_DEBUG_LOG "keycache_debug.log"
...
@@ -231,9 +239,9 @@ static long keycache_thread_id;
...
@@ -231,9 +239,9 @@ static long keycache_thread_id;
#endif
/* defined(KEYCACHE_DEBUG) || !defined(DBUG_OFF) */
#endif
/* defined(KEYCACHE_DEBUG) || !defined(DBUG_OFF) */
#define BLOCK_NUMBER(b) \
#define BLOCK_NUMBER(b) \
((uint) (((char*)(b) - (char *) my_block_root) /
sizeof(BLOCK_LINK)))
((uint) (((char*)(b)-(char *) keycache->block_root)/
sizeof(BLOCK_LINK)))
#define HASH_LINK_NUMBER(h) \
#define HASH_LINK_NUMBER(h) \
((uint) (((char*)(h) - (char *) my_hash_link_root) /
sizeof(HASH_LINK)))
((uint) (((char*)(h)-(char *) keycache->hash_link_root)/
sizeof(HASH_LINK)))
#if (defined(KEYCACHE_TIMEOUT) && !defined(__WIN__)) || defined(KEYCACHE_DEBUG)
#if (defined(KEYCACHE_TIMEOUT) && !defined(__WIN__)) || defined(KEYCACHE_DEBUG)
static
int
keycache_pthread_cond_wait
(
pthread_cond_t
*
cond
,
static
int
keycache_pthread_cond_wait
(
pthread_cond_t
*
cond
,
...
@@ -271,111 +279,131 @@ static uint next_power(uint value)
...
@@ -271,111 +279,131 @@ static uint next_power(uint value)
return number of blocks in it
return number of blocks in it
*/
*/
int
init_key_cache
(
ulong
use_mem
)
int
init_key_cache
(
void
**
pkeycache
,
uint
key_cache_block_size
,
ulong
use_mem
)
{
{
uint
blocks
,
hash_links
,
length
;
uint
blocks
,
hash_links
,
length
;
int
error
;
int
error
;
KEY_CACHE
*
keycache
;
DBUG_ENTER
(
"init_key_cache"
);
DBUG_ENTER
(
"init_key_cache"
);
if
(
!*
pkeycache
)
{
if
(
!
(
*
pkeycache
=
my_malloc
(
sizeof
(
KEY_CACHE
),
MYF
(
MY_ZEROFILL
))))
DBUG_RETURN
(
0
);
}
keycache
=
(
KEY_CACHE
*
)
*
pkeycache
;
KEYCACHE_DEBUG_OPEN
;
KEYCACHE_DEBUG_OPEN
;
if
(
key
_cache_inited
&&
my_
disk_blocks
>
0
)
if
(
key
cache
->
key_cache_inited
&&
keycache
->
disk_blocks
>
0
)
{
{
DBUG_PRINT
(
"warning"
,(
"key cache already in use"
));
DBUG_PRINT
(
"warning"
,(
"key cache already in use"
));
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
if
(
!
key_cache_inited
)
if
(
!
key
cache
->
key
_cache_inited
)
{
{
key_cache_inited
=
TRUE
;
keycache
->
key_cache_inited
=
TRUE
;
my_disk_blocks
=
-
1
;
keycache
->
disk_blocks
=
-
1
;
key_cache_shift
=
my_bit_log2
(
key_cache_block_size
);
pthread_mutex_init
(
&
keycache
->
thr_lock_keycache
,
MY_MUTEX_INIT_FAST
);
keycache
->
key_cache_shift
=
my_bit_log2
(
key_cache_block_size
);
keycache
->
key_cache_block_size
=
key_cache_block_size
;
DBUG_PRINT
(
"info"
,(
"key_cache_block_size: %u"
,
DBUG_PRINT
(
"info"
,(
"key_cache_block_size: %u"
,
key_cache_block_size
));
key_cache_block_size
));
}
}
my_cache_w_requests
=
my_cache_r_requests
=
my_cache_read
=
my_cache_write
=
0
;
keycache
->
cache_w_requests
=
keycache
->
cache_r_requests
=
0
;
keycache
->
cache_read
=
keycache
->
cache_write
=
0
;
my_block_mem
=
NULL
;
keycache
->
block_mem
=
NULL
;
my_block_root
=
NULL
;
keycache
->
block_root
=
NULL
;
blocks
=
(
uint
)
(
use_mem
/
(
sizeof
(
BLOCK_LINK
)
+
2
*
sizeof
(
HASH_LINK
)
+
blocks
=
(
uint
)
(
use_mem
/
(
sizeof
(
BLOCK_LINK
)
+
2
*
sizeof
(
HASH_LINK
)
+
sizeof
(
HASH_LINK
*
)
*
5
/
4
+
key_cache_block_size
));
sizeof
(
HASH_LINK
*
)
*
5
/
4
+
key_cache_block_size
));
/* It doesn't make sense to have too few blocks (less than 8) */
/* It doesn't make sense to have too few blocks (less than 8) */
if
(
blocks
>=
8
&&
my_
disk_blocks
<
0
)
if
(
blocks
>=
8
&&
keycache
->
disk_blocks
<
0
)
{
{
for
(;;)
for
(;;)
{
{
/* Set my_hash_entries to the next bigger 2 power */
/* Set my_hash_entries to the next bigger 2 power */
if
((
my_hash_entries
=
next_power
(
blocks
))
<
blocks
*
5
/
4
)
if
((
keycache
->
hash_entries
=
next_power
(
blocks
))
<
blocks
*
5
/
4
)
my_hash_entries
<<=
1
;
keycache
->
hash_entries
<<=
1
;
hash_links
=
2
*
blocks
;
hash_links
=
2
*
blocks
;
#if defined(MAX_THREADS)
#if defined(MAX_THREADS)
if
(
hash_links
<
MAX_THREADS
+
blocks
-
1
)
if
(
hash_links
<
MAX_THREADS
+
blocks
-
1
)
hash_links
=
MAX_THREADS
+
blocks
-
1
;
hash_links
=
MAX_THREADS
+
blocks
-
1
;
#endif
#endif
while
((
length
=
(
ALIGN_SIZE
(
blocks
*
sizeof
(
BLOCK_LINK
))
+
while
((
length
=
(
ALIGN_SIZE
(
blocks
*
sizeof
(
BLOCK_LINK
))
+
ALIGN_SIZE
(
hash_links
*
sizeof
(
HASH_LINK
))
+
ALIGN_SIZE
(
hash_links
*
sizeof
(
HASH_LINK
))
+
ALIGN_SIZE
(
sizeof
(
HASH_LINK
*
)
*
my_
hash_entries
)))
+
ALIGN_SIZE
(
sizeof
(
HASH_LINK
*
)
*
keycache
->
hash_entries
)))
+
((
ulong
)
blocks
<<
key_cache_shift
)
>
use_mem
)
((
ulong
)
blocks
<<
key
cache
->
key
_cache_shift
)
>
use_mem
)
blocks
--
;
blocks
--
;
/* Allocate memory for cache page buffers */
/* Allocate memory for cache page buffers */
if
((
my_block_mem
=
my_malloc_lock
((
ulong
)
blocks
*
key_cache_block_size
,
if
((
keycache
->
block_mem
=
MYF
(
0
))))
my_malloc_lock
((
ulong
)
blocks
*
keycache
->
key_cache_block_size
,
MYF
(
0
))))
{
{
/*
/*
Allocate memory for blocks, hash_links and hash entries;
Allocate memory for blocks, hash_links and hash entries;
For each block 2 hash links are allocated
For each block 2 hash links are allocated
*/
*/
if
((
my_block_root
=
(
BLOCK_LINK
*
)
my_malloc
((
uint
)
length
,
MYF
(
0
))))
if
((
keycache
->
block_root
=
(
BLOCK_LINK
*
)
my_malloc
((
uint
)
length
,
MYF
(
0
))))
break
;
break
;
my_free_lock
(
my_block_mem
,
MYF
(
0
));
my_free_lock
(
keycache
->
block_mem
,
MYF
(
0
));
}
}
if
(
blocks
<
8
)
if
(
blocks
<
8
)
{
{
my_errno
=
ENOMEM
;
my_errno
=
ENOMEM
;
goto
err
;
goto
err
;
}
}
blocks
=
blocks
/
4
*
3
;
blocks
=
blocks
/
4
*
3
;
}
}
my_disk_blocks
=
(
int
)
blocks
;
keycache
->
disk_blocks
=
(
int
)
blocks
;
my_hash_links
=
hash_links
;
keycache
->
hash_links
=
hash_links
;
my_hash_root
=
(
HASH_LINK
**
)
((
char
*
)
my_block_root
+
keycache
->
hash_root
=
(
HASH_LINK
**
)
((
char
*
)
keycache
->
block_root
+
ALIGN_SIZE
(
blocks
*
sizeof
(
BLOCK_LINK
)));
ALIGN_SIZE
(
blocks
*
sizeof
(
BLOCK_LINK
)));
my_hash_link_root
=
(
HASH_LINK
*
)
((
char
*
)
my_hash_root
+
keycache
->
hash_link_root
=
(
HASH_LINK
*
)
((
char
*
)
keycache
->
hash_root
+
ALIGN_SIZE
((
sizeof
(
HASH_LINK
*
)
*
ALIGN_SIZE
((
sizeof
(
HASH_LINK
*
)
*
my_hash_entries
)));
keycache
->
hash_entries
)));
bzero
((
byte
*
)
my_block_root
,
my_disk_blocks
*
sizeof
(
BLOCK_LINK
));
bzero
((
byte
*
)
keycache
->
block_root
,
bzero
((
byte
*
)
my_hash_root
,
my_hash_entries
*
sizeof
(
HASH_LINK
*
));
keycache
->
disk_blocks
*
sizeof
(
BLOCK_LINK
));
bzero
((
byte
*
)
my_hash_link_root
,
my_hash_links
*
sizeof
(
HASH_LINK
));
bzero
((
byte
*
)
keycache
->
hash_root
,
my_hash_links_used
=
0
;
keycache
->
hash_entries
*
sizeof
(
HASH_LINK
*
));
my_free_hash_list
=
NULL
;
bzero
((
byte
*
)
keycache
->
hash_link_root
,
my_blocks_used
=
my_blocks_changed
=
0
;
keycache
->
hash_links
*
sizeof
(
HASH_LINK
));
keycache
->
hash_links_used
=
0
;
keycache
->
free_hash_list
=
NULL
;
keycache
->
blocks_used
=
keycache
->
blocks_changed
=
0
;
#if defined(KEYCACHE_DEBUG)
#if defined(KEYCACHE_DEBUG)
my
_blocks_available
=
0
;
keycache
->
_blocks_available
=
0
;
#endif
#endif
/* The LRU chain is empty after initialization */
/* The LRU chain is empty after initialization */
my_
used_last
=
NULL
;
keycache
->
used_last
=
NULL
;
waiting_for_hash_link
.
last_thread
=
NULL
;
keycache
->
waiting_for_hash_link
.
last_thread
=
NULL
;
waiting_for_block
.
last_thread
=
NULL
;
keycache
->
waiting_for_block
.
last_thread
=
NULL
;
DBUG_PRINT
(
"exit"
,
DBUG_PRINT
(
"exit"
,
(
"disk_blocks: %d block_root: %lx hash_entries: %d hash_root: %lx \
(
"disk_blocks: %d block_root: %lx hash_entries: %d hash_root: %lx \
hash_links: %d hash_link_root %lx"
,
hash_links: %d hash_link_root %lx"
,
my_disk_blocks
,
my_block_root
,
my_hash_entries
,
my_hash_root
,
keycache
->
disk_blocks
,
keycache
->
block_root
,
my_hash_links
,
my_hash_link_root
));
keycache
->
hash_entries
,
keycache
->
hash_root
,
keycache
->
hash_links
,
keycache
->
hash_link_root
));
}
}
bzero
((
gptr
)
changed_blocks
,
sizeof
(
changed_blocks
[
0
])
*
CHANGED_BLOCKS_HASH
);
bzero
((
gptr
)
keycache
->
changed_blocks
,
bzero
((
gptr
)
file_blocks
,
sizeof
(
file_blocks
[
0
])
*
CHANGED_BLOCKS_HASH
);
sizeof
(
keycache
->
changed_blocks
[
0
])
*
CHANGED_BLOCKS_HASH
);
bzero
((
gptr
)
keycache
->
file_blocks
,
sizeof
(
keycache
->
file_blocks
[
0
])
*
CHANGED_BLOCKS_HASH
);
DBUG_RETURN
((
int
)
blocks
);
DBUG_RETURN
((
int
)
blocks
);
err:
err:
error
=
my_errno
;
error
=
my_errno
;
if
(
my_
block_mem
)
if
(
keycache
->
block_mem
)
my_free_lock
((
gptr
)
my_block_mem
,
MYF
(
0
));
my_free_lock
((
gptr
)
keycache
->
block_mem
,
MYF
(
0
));
if
(
my_
block_mem
)
if
(
keycache
->
block_mem
)
my_free
((
gptr
)
my_
block_root
,
MYF
(
0
));
my_free
((
gptr
)
keycache
->
block_root
,
MYF
(
0
));
my_errno
=
error
;
my_errno
=
error
;
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
...
@@ -383,20 +411,23 @@ err:
...
@@ -383,20 +411,23 @@ err:
/*
/*
Resize the key cache
Resize the key cache
*/
*/
int
resize_key_cache
(
ulong
use_mem
)
int
resize_key_cache
(
void
**
pkeycache
,
ulong
use_mem
)
{
{
int
blocks
;
int
blocks
;
keycache_pthread_mutex_lock
(
&
THR_LOCK_keycache
);
KEY_CACHE
*
keycache
=
(
KEY_CACHE
*
)
*
pkeycache
;
uint
key_cache_block_size
=
keycache
->
key_cache_block_size
;
keycache_pthread_mutex_lock
(
&
keycache
->
thr_lock_keycache
);
if
(
flush_all_key_blocks
())
if
(
flush_all_key_blocks
())
{
{
/* TODO: if this happens, we should write a warning in the log file ! */
/* TODO: if this happens, we should write a warning in the log file ! */
keycache_pthread_mutex_unlock
(
&
THR_LOCK
_keycache
);
keycache_pthread_mutex_unlock
(
&
keycache
->
thr_lock
_keycache
);
return
0
;
return
0
;
}
}
end_key_cache
();
keycache_pthread_mutex_unlock
(
&
keycache
->
thr_lock_keycache
);
end_key_cache
(
pkeycache
,
0
);
/* the following will work even if memory is 0 */
/* the following will work even if memory is 0 */
blocks
=
init_key_cache
(
use_mem
);
blocks
=
init_key_cache
(
pkeycache
,
key_cache_block_size
,
use_mem
);
keycache_pthread_mutex_unlock
(
&
THR_LOCK_keycache
);
return
blocks
;
return
blocks
;
}
}
...
@@ -405,25 +436,33 @@ int resize_key_cache(ulong use_mem)
...
@@ -405,25 +436,33 @@ int resize_key_cache(ulong use_mem)
Remove key_cache from memory
Remove key_cache from memory
*/
*/
void
end_key_cache
(
void
)
void
end_key_cache
(
void
**
pkeycache
,
my_bool
cleanup
)
{
{
KEY_CACHE
*
keycache
=
(
KEY_CACHE
*
)
*
pkeycache
;
DBUG_ENTER
(
"end_key_cache"
);
DBUG_ENTER
(
"end_key_cache"
);
if
(
my_
disk_blocks
>
0
)
if
(
keycache
->
disk_blocks
>
0
)
{
{
if
(
my_
block_mem
)
if
(
keycache
->
block_mem
)
{
{
my_free_lock
((
gptr
)
my_block_mem
,
MYF
(
0
));
my_free_lock
((
gptr
)
keycache
->
block_mem
,
MYF
(
0
));
my_free
((
gptr
)
my_block_root
,
MYF
(
0
));
my_free
((
gptr
)
keycache
->
block_root
,
MYF
(
0
));
}
}
my_
disk_blocks
=
-
1
;
keycache
->
disk_blocks
=
-
1
;
}
}
KEYCACHE_DEBUG_CLOSE
;
KEYCACHE_DEBUG_CLOSE
;
key_cache_inited
=
0
;
key
cache
->
key
_cache_inited
=
0
;
DBUG_PRINT
(
"status"
,
DBUG_PRINT
(
"status"
,
(
"used: %d changed: %d w_requests: %ld \
(
"used: %d changed: %d w_requests: %ld \
writes: %ld r_requests: %ld reads: %ld"
,
writes: %ld r_requests: %ld reads: %ld"
,
my_blocks_used
,
my_blocks_changed
,
my_cache_w_requests
,
keycache
->
blocks_used
,
keycache
->
blocks_changed
,
my_cache_write
,
my_cache_r_requests
,
my_cache_read
));
keycache
->
cache_w_requests
,
keycache
->
cache_write
,
keycache
->
cache_r_requests
,
keycache
->
cache_read
));
if
(
cleanup
)
{
pthread_mutex_destroy
(
&
keycache
->
thr_lock_keycache
);
my_free
(
*
pkeycache
,
MYF
(
0
));
*
pkeycache
=
NULL
;
}
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
/* end_key_cache */
}
/* end_key_cache */
...
@@ -546,16 +585,16 @@ static inline void link_changed(BLOCK_LINK *block, BLOCK_LINK **phead)
...
@@ -546,16 +585,16 @@ static inline void link_changed(BLOCK_LINK *block, BLOCK_LINK **phead)
and link it to the chain of clean blocks for the specified file
and link it to the chain of clean blocks for the specified file
*/
*/
static
void
link_to_file_list
(
BLOCK_LINK
*
block
,
int
fil
e
,
static
void
link_to_file_list
(
KEY_CACHE
*
keycach
e
,
my_bool
unlink
)
BLOCK_LINK
*
block
,
int
file
,
my_bool
unlink
)
{
{
if
(
unlink
)
if
(
unlink
)
unlink_changed
(
block
);
unlink_changed
(
block
);
link_changed
(
block
,
&
file_blocks
[
FILE_HASH
(
file
)]);
link_changed
(
block
,
&
keycache
->
file_blocks
[
FILE_HASH
(
file
)]);
if
(
block
->
status
&
BLOCK_CHANGED
)
if
(
block
->
status
&
BLOCK_CHANGED
)
{
{
block
->
status
&=~
BLOCK_CHANGED
;
block
->
status
&=~
BLOCK_CHANGED
;
my_
blocks_changed
--
;
keycache
->
blocks_changed
--
;
}
}
}
}
...
@@ -565,12 +604,14 @@ static void link_to_file_list(BLOCK_LINK *block,int file,
...
@@ -565,12 +604,14 @@ static void link_to_file_list(BLOCK_LINK *block,int file,
file and link it to the chain of dirty blocks for this file
file and link it to the chain of dirty blocks for this file
*/
*/
static
inline
void
link_to_changed_list
(
BLOCK_LINK
*
block
)
static
inline
void
link_to_changed_list
(
KEY_CACHE
*
keycache
,
BLOCK_LINK
*
block
)
{
{
unlink_changed
(
block
);
unlink_changed
(
block
);
link_changed
(
block
,
&
changed_blocks
[
FILE_HASH
(
block
->
hash_link
->
file
)]);
link_changed
(
block
,
&
keycache
->
changed_blocks
[
FILE_HASH
(
block
->
hash_link
->
file
)]);
block
->
status
|=
BLOCK_CHANGED
;
block
->
status
|=
BLOCK_CHANGED
;
my_
blocks_changed
++
;
keycache
->
blocks_changed
++
;
}
}
...
@@ -578,14 +619,15 @@ static inline void link_to_changed_list(BLOCK_LINK *block)
...
@@ -578,14 +619,15 @@ static inline void link_to_changed_list(BLOCK_LINK *block)
Link a block to the LRU chain at the beginning or at the end
Link a block to the LRU chain at the beginning or at the end
*/
*/
static
void
link_block
(
BLOCK_LINK
*
block
,
my_bool
at_end
)
static
void
link_block
(
KEY_CACHE
*
keycache
,
BLOCK_LINK
*
block
,
my_bool
at_end
)
{
{
KEYCACHE_DBUG_ASSERT
(
!
(
block
->
hash_link
&&
block
->
hash_link
->
requests
));
KEYCACHE_DBUG_ASSERT
(
!
(
block
->
hash_link
&&
block
->
hash_link
->
requests
));
if
(
waiting_for_block
.
last_thread
)
{
if
(
keycache
->
waiting_for_block
.
last_thread
)
{
/* Signal that in the LRU chain an available block has appeared */
/* Signal that in the LRU chain an available block has appeared */
struct
st_my_thread_var
*
last_thread
=
waiting_for_block
.
last_thread
;
struct
st_my_thread_var
*
last_thread
=
struct
st_my_thread_var
*
first_thread
=
last_thread
->
next
;
keycache
->
waiting_for_block
.
last_thread
;
struct
st_my_thread_var
*
next_thread
=
first_thread
;
struct
st_my_thread_var
*
first_thread
=
last_thread
->
next
;
struct
st_my_thread_var
*
next_thread
=
first_thread
;
HASH_LINK
*
hash_link
=
(
HASH_LINK
*
)
first_thread
->
opt_info
;
HASH_LINK
*
hash_link
=
(
HASH_LINK
*
)
first_thread
->
opt_info
;
struct
st_my_thread_var
*
thread
;
struct
st_my_thread_var
*
thread
;
do
do
...
@@ -599,44 +641,44 @@ static void link_block(BLOCK_LINK *block, my_bool at_end)
...
@@ -599,44 +641,44 @@ static void link_block(BLOCK_LINK *block, my_bool at_end)
if
((
HASH_LINK
*
)
thread
->
opt_info
==
hash_link
)
if
((
HASH_LINK
*
)
thread
->
opt_info
==
hash_link
)
{
{
keycache_pthread_cond_signal
(
&
thread
->
suspend
);
keycache_pthread_cond_signal
(
&
thread
->
suspend
);
unlink_from_queue
(
&
waiting_for_block
,
thread
);
unlink_from_queue
(
&
keycache
->
waiting_for_block
,
thread
);
block
->
requests
++
;
block
->
requests
++
;
}
}
}
}
while
(
thread
!=
last_thread
);
while
(
thread
!=
last_thread
);
hash_link
->
block
=
block
;
hash_link
->
block
=
block
;
KEYCACHE_THREAD_TRACE
(
"link_block: after signaling"
);
KEYCACHE_THREAD_TRACE
(
"link_block: after signaling"
);
#if defined(KEYCACHE_DEBUG)
#if defined(KEYCACHE_DEBUG)
KEYCACHE_DBUG_PRINT
(
"link_block"
,
KEYCACHE_DBUG_PRINT
(
"link_block"
,
(
"linked,unlinked block %u status=%x #requests=%u #available=%u"
,
(
"linked,unlinked block %u status=%x #requests=%u #available=%u"
,
BLOCK_NUMBER
(
block
),
block
->
status
,
BLOCK_NUMBER
(
block
),
block
->
status
,
block
->
requests
,
my_
blocks_available
));
block
->
requests
,
blocks_available
));
#endif
#endif
return
;
return
;
}
}
if
(
my_
used_last
)
if
(
keycache
->
used_last
)
{
{
my_used_last
->
next_used
->
prev_used
=
&
block
->
next_used
;
keycache
->
used_last
->
next_used
->
prev_used
=
&
block
->
next_used
;
block
->
next_used
=
my_
used_last
->
next_used
;
block
->
next_used
=
keycache
->
used_last
->
next_used
;
block
->
prev_used
=
&
my_
used_last
->
next_used
;
block
->
prev_used
=
&
keycache
->
used_last
->
next_used
;
my_used_last
->
next_used
=
block
;
keycache
->
used_last
->
next_used
=
block
;
if
(
at_end
)
if
(
at_end
)
my_used_last
=
block
;
keycache
->
used_last
=
block
;
}
}
else
else
{
{
/* The LRU chain is empty */
/* The LRU chain is empty */
my_used_last
=
block
->
next_used
=
block
;
keycache
->
used_last
=
block
->
next_used
=
block
;
block
->
prev_used
=&
block
->
next_used
;
block
->
prev_used
=
&
block
->
next_used
;
}
}
KEYCACHE_THREAD_TRACE
(
"link_block"
);
KEYCACHE_THREAD_TRACE
(
"link_block"
);
#if defined(KEYCACHE_DEBUG)
#if defined(KEYCACHE_DEBUG)
my_
blocks_available
++
;
keycache
->
blocks_available
++
;
KEYCACHE_DBUG_PRINT
(
"link_block"
,
KEYCACHE_DBUG_PRINT
(
"link_block"
,
(
"linked block %u:%1u status=%x #requests=%u #available=%u"
,
(
"linked block %u:%1u status=%x #requests=%u #available=%u"
,
BLOCK_NUMBER
(
block
),
at_end
,
block
->
status
,
BLOCK_NUMBER
(
block
),
at_end
,
block
->
status
,
block
->
requests
,
my_
blocks_available
));
block
->
requests
,
keycache
->
blocks_available
));
KEYCACHE_DBUG_ASSERT
(
my_blocks_available
<=
my_
blocks_used
);
KEYCACHE_DBUG_ASSERT
(
keycache
->
blocks_available
<=
keycache
->
blocks_used
);
#endif
#endif
}
}
...
@@ -645,28 +687,28 @@ static void link_block(BLOCK_LINK *block, my_bool at_end)
...
@@ -645,28 +687,28 @@ static void link_block(BLOCK_LINK *block, my_bool at_end)
Unlink a block from the LRU chain
Unlink a block from the LRU chain
*/
*/
static
void
unlink_block
(
BLOCK_LINK
*
block
)
static
void
unlink_block
(
KEY_CACHE
*
keycache
,
BLOCK_LINK
*
block
)
{
{
if
(
block
->
next_used
==
block
)
if
(
block
->
next_used
==
block
)
/* The list contains only one member */
/* The list contains only one member */
my_used_last
=
NULL
;
keycache
->
used_last
=
NULL
;
else
else
{
{
block
->
next_used
->
prev_used
=
block
->
prev_used
;
block
->
next_used
->
prev_used
=
block
->
prev_used
;
*
block
->
prev_used
=
block
->
next_used
;
*
block
->
prev_used
=
block
->
next_used
;
if
(
my_
used_last
==
block
)
if
(
keycache
->
used_last
==
block
)
my_used_last
=
STRUCT_PTR
(
BLOCK_LINK
,
next_used
,
block
->
prev_used
);
keycache
->
used_last
=
STRUCT_PTR
(
BLOCK_LINK
,
next_used
,
block
->
prev_used
);
}
}
block
->
next_used
=
NULL
;
block
->
next_used
=
NULL
;
KEYCACHE_THREAD_TRACE
(
"unlink_block"
);
KEYCACHE_THREAD_TRACE
(
"unlink_block"
);
#if defined(KEYCACHE_DEBUG)
#if defined(KEYCACHE_DEBUG)
my_
blocks_available
--
;
keycache
->
blocks_available
--
;
KEYCACHE_DBUG_PRINT
(
"unlink_block"
,
KEYCACHE_DBUG_PRINT
(
"unlink_block"
,
(
"unlinked block %u status=%x #requests=%u #available=%u"
,
(
"unlinked block %u status=%x #requests=%u #available=%u"
,
BLOCK_NUMBER
(
block
),
block
->
status
,
BLOCK_NUMBER
(
block
),
block
->
status
,
block
->
requests
,
my_
blocks_available
));
block
->
requests
,
keycache
->
blocks_available
));
KEYCACHE_DBUG_ASSERT
(
my_
blocks_available
>=
0
);
KEYCACHE_DBUG_ASSERT
(
keycache
->
blocks_available
>=
0
);
#endif
#endif
}
}
...
@@ -674,11 +716,11 @@ static void unlink_block(BLOCK_LINK *block)
...
@@ -674,11 +716,11 @@ static void unlink_block(BLOCK_LINK *block)
/*
/*
Register requests for a block
Register requests for a block
*/
*/
static
void
reg_requests
(
BLOCK_LINK
*
block
,
int
count
)
static
void
reg_requests
(
KEY_CACHE
*
keycache
,
BLOCK_LINK
*
block
,
int
count
)
{
{
if
(
!
block
->
requests
)
if
(
!
block
->
requests
)
/* First request for the block unlinks it */
/* First request for the block unlinks it */
unlink_block
(
block
);
unlink_block
(
keycache
,
block
);
block
->
requests
+=
count
;
block
->
requests
+=
count
;
}
}
...
@@ -688,10 +730,11 @@ static void reg_requests(BLOCK_LINK *block, int count)
...
@@ -688,10 +730,11 @@ static void reg_requests(BLOCK_LINK *block, int count)
linking it to the LRU chain if it's the last request
linking it to the LRU chain if it's the last request
*/
*/
static
inline
void
unreg_request
(
BLOCK_LINK
*
block
,
int
at_end
)
static
inline
void
unreg_request
(
KEY_CACHE
*
keycache
,
BLOCK_LINK
*
block
,
int
at_end
)
{
{
if
(
!
--
block
->
requests
)
if
(
!
--
block
->
requests
)
link_block
(
block
,
(
my_bool
)
at_end
);
link_block
(
keycache
,
block
,
(
my_bool
)
at_end
);
}
}
/*
/*
...
@@ -709,13 +752,13 @@ static inline void remove_reader(BLOCK_LINK *block)
...
@@ -709,13 +752,13 @@ static inline void remove_reader(BLOCK_LINK *block)
Wait until the last reader of the page in block
Wait until the last reader of the page in block
signals on its termination
signals on its termination
*/
*/
static
inline
void
wait_for_readers
(
BLOCK_LINK
*
block
)
static
inline
void
wait_for_readers
(
KEY_CACHE
*
keycache
,
BLOCK_LINK
*
block
)
{
{
struct
st_my_thread_var
*
thread
=
my_thread_var
;
struct
st_my_thread_var
*
thread
=
my_thread_var
;
while
(
block
->
hash_link
->
requests
)
while
(
block
->
hash_link
->
requests
)
{
{
block
->
condvar
=&
thread
->
suspend
;
block
->
condvar
=&
thread
->
suspend
;
keycache_pthread_cond_wait
(
&
thread
->
suspend
,
&
THR_LOCK
_keycache
);
keycache_pthread_cond_wait
(
&
thread
->
suspend
,
&
keycache
->
thr_lock
_keycache
);
block
->
condvar
=
NULL
;
block
->
condvar
=
NULL
;
}
}
}
}
...
@@ -728,10 +771,10 @@ static inline void wait_for_readers(BLOCK_LINK *block)
...
@@ -728,10 +771,10 @@ static inline void wait_for_readers(BLOCK_LINK *block)
static
inline
void
link_hash
(
HASH_LINK
**
start
,
HASH_LINK
*
hash_link
)
static
inline
void
link_hash
(
HASH_LINK
**
start
,
HASH_LINK
*
hash_link
)
{
{
if
(
*
start
)
if
(
*
start
)
(
*
start
)
->
prev
=&
hash_link
->
next
;
(
*
start
)
->
prev
=
&
hash_link
->
next
;
hash_link
->
next
=*
start
;
hash_link
->
next
=
*
start
;
hash_link
->
prev
=
start
;
hash_link
->
prev
=
start
;
*
start
=
hash_link
;
*
start
=
hash_link
;
}
}
...
@@ -739,31 +782,32 @@ static inline void link_hash(HASH_LINK **start, HASH_LINK *hash_link)
...
@@ -739,31 +782,32 @@ static inline void link_hash(HASH_LINK **start, HASH_LINK *hash_link)
Remove a hash link from the hash table
Remove a hash link from the hash table
*/
*/
static
void
unlink_hash
(
HASH_LINK
*
hash_link
)
static
void
unlink_hash
(
KEY_CACHE
*
keycache
,
HASH_LINK
*
hash_link
)
{
{
KEYCACHE_DBUG_PRINT
(
"unlink_hash"
,
(
"file %u, filepos %lu #requests=%u"
,
KEYCACHE_DBUG_PRINT
(
"unlink_hash"
,
(
"file %u, filepos %lu #requests=%u"
,
(
uint
)
hash_link
->
file
,(
ulong
)
hash_link
->
diskpos
,
hash_link
->
requests
));
(
uint
)
hash_link
->
file
,(
ulong
)
hash_link
->
diskpos
,
hash_link
->
requests
));
KEYCACHE_DBUG_ASSERT
(
hash_link
->
requests
==
0
);
KEYCACHE_DBUG_ASSERT
(
hash_link
->
requests
==
0
);
if
((
*
hash_link
->
prev
=
hash_link
->
next
))
if
((
*
hash_link
->
prev
=
hash_link
->
next
))
hash_link
->
next
->
prev
=
hash_link
->
prev
;
hash_link
->
next
->
prev
=
hash_link
->
prev
;
hash_link
->
block
=
NULL
;
hash_link
->
block
=
NULL
;
if
(
waiting_for_hash_link
.
last_thread
)
if
(
keycache
->
waiting_for_hash_link
.
last_thread
)
{
{
/* Signal that A free hash link appeared */
/* Signal that A free hash link appeared */
struct
st_my_thread_var
*
last_thread
=
waiting_for_hash_link
.
last_thread
;
struct
st_my_thread_var
*
last_thread
=
struct
st_my_thread_var
*
first_thread
=
last_thread
->
next
;
keycache
->
waiting_for_hash_link
.
last_thread
;
struct
st_my_thread_var
*
next_thread
=
first_thread
;
struct
st_my_thread_var
*
first_thread
=
last_thread
->
next
;
struct
st_my_thread_var
*
next_thread
=
first_thread
;
KEYCACHE_PAGE
*
first_page
=
(
KEYCACHE_PAGE
*
)
(
first_thread
->
opt_info
);
KEYCACHE_PAGE
*
first_page
=
(
KEYCACHE_PAGE
*
)
(
first_thread
->
opt_info
);
struct
st_my_thread_var
*
thread
;
struct
st_my_thread_var
*
thread
;
hash_link
->
file
=
first_page
->
file
;
hash_link
->
file
=
first_page
->
file
;
hash_link
->
diskpos
=
first_page
->
filepos
;
hash_link
->
diskpos
=
first_page
->
filepos
;
do
do
{
{
KEYCACHE_PAGE
*
page
;
KEYCACHE_PAGE
*
page
;
thread
=
next_thread
;
thread
=
next_thread
;
page
=
(
KEYCACHE_PAGE
*
)
thread
->
opt_info
;
page
=
(
KEYCACHE_PAGE
*
)
thread
->
opt_info
;
next_thread
=
thread
->
next
;
next_thread
=
thread
->
next
;
/*
/*
We notify about the event all threads that ask
We notify about the event all threads that ask
for the same page as the first thread in the queue
for the same page as the first thread in the queue
...
@@ -771,16 +815,17 @@ static void unlink_hash(HASH_LINK *hash_link)
...
@@ -771,16 +815,17 @@ static void unlink_hash(HASH_LINK *hash_link)
if
(
page
->
file
==
hash_link
->
file
&&
page
->
filepos
==
hash_link
->
diskpos
)
if
(
page
->
file
==
hash_link
->
file
&&
page
->
filepos
==
hash_link
->
diskpos
)
{
{
keycache_pthread_cond_signal
(
&
thread
->
suspend
);
keycache_pthread_cond_signal
(
&
thread
->
suspend
);
unlink_from_queue
(
&
waiting_for_hash_link
,
thread
);
unlink_from_queue
(
&
keycache
->
waiting_for_hash_link
,
thread
);
}
}
}
}
while
(
thread
!=
last_thread
);
while
(
thread
!=
last_thread
);
link_hash
(
&
my_hash_root
[
KEYCACHE_HASH
(
hash_link
->
file
,
link_hash
(
&
keycache
->
hash_root
[
KEYCACHE_HASH
(
hash_link
->
file
,
hash_link
->
diskpos
)],
hash_link
);
hash_link
->
diskpos
)],
hash_link
);
return
;
return
;
}
}
hash_link
->
next
=
my_
free_hash_list
;
hash_link
->
next
=
keycache
->
free_hash_list
;
my_free_hash_list
=
hash_link
;
keycache
->
free_hash_list
=
hash_link
;
}
}
...
@@ -788,7 +833,8 @@ static void unlink_hash(HASH_LINK *hash_link)
...
@@ -788,7 +833,8 @@ static void unlink_hash(HASH_LINK *hash_link)
Get the hash link for a page
Get the hash link for a page
*/
*/
static
HASH_LINK
*
get_hash_link
(
int
file
,
my_off_t
filepos
)
static
HASH_LINK
*
get_hash_link
(
KEY_CACHE
*
keycache
,
int
file
,
my_off_t
filepos
)
{
{
reg1
HASH_LINK
*
hash_link
,
**
start
;
reg1
HASH_LINK
*
hash_link
,
**
start
;
KEYCACHE_PAGE
page
;
KEYCACHE_PAGE
page
;
...
@@ -805,9 +851,9 @@ restart:
...
@@ -805,9 +851,9 @@ restart:
start contains the head of the bucket list,
start contains the head of the bucket list,
hash_link points to the first member of the list
hash_link points to the first member of the list
*/
*/
hash_link
=
*
(
start
=
&
my_
hash_root
[
KEYCACHE_HASH
(
file
,
filepos
)]);
hash_link
=
*
(
start
=
&
keycache
->
hash_root
[
KEYCACHE_HASH
(
file
,
filepos
)]);
#if defined(KEYCACHE_DEBUG)
#if defined(KEYCACHE_DEBUG)
cnt
=
0
;
cnt
=
0
;
#endif
#endif
/* Look for an element for the pair (file, filepos) in the bucket chain */
/* Look for an element for the pair (file, filepos) in the bucket chain */
while
(
hash_link
&&
while
(
hash_link
&&
...
@@ -819,42 +865,43 @@ restart:
...
@@ -819,42 +865,43 @@ restart:
if
(
!
(
cnt
<=
my_hash_links_used
))
if
(
!
(
cnt
<=
my_hash_links_used
))
{
{
int
i
;
int
i
;
for
(
i
=
0
,
hash_link
=*
start
;
for
(
i
=
0
,
hash_link
=
*
start
;
i
<
cnt
;
i
++
,
hash_link
=
hash_link
->
next
)
i
<
cnt
;
i
++
,
hash_link
=
hash_link
->
next
)
{
{
KEYCACHE_DBUG_PRINT
(
"get_hash_link"
,
(
"file %u, filepos %lu"
,
KEYCACHE_DBUG_PRINT
(
"get_hash_link"
,
(
"file %u, filepos %lu"
,
(
uint
)
hash_link
->
file
,(
ulong
)
hash_link
->
diskpos
));
(
uint
)
hash_link
->
file
,(
ulong
)
hash_link
->
diskpos
));
}
}
}
}
KEYCACHE_DBUG_ASSERT
(
cnt
<=
my_
hash_links_used
);
KEYCACHE_DBUG_ASSERT
(
cnt
<=
keycache
->
hash_links_used
);
#endif
#endif
}
}
if
(
!
hash_link
)
if
(
!
hash_link
)
{
{
/* There is no hash link in the hash table for the pair (file, filepos) */
/* There is no hash link in the hash table for the pair (file, filepos) */
if
(
my_
free_hash_list
)
if
(
keycache
->
free_hash_list
)
{
{
hash_link
=
my_
free_hash_list
;
hash_link
=
keycache
->
free_hash_list
;
my_
free_hash_list
=
hash_link
->
next
;
keycache
->
free_hash_list
=
hash_link
->
next
;
}
}
else
if
(
my_hash_links_used
<
my_
hash_links
)
else
if
(
keycache
->
hash_links_used
<
keycache
->
hash_links
)
{
{
hash_link
=
&
my_hash_link_root
[
my_
hash_links_used
++
];
hash_link
=
&
keycache
->
hash_link_root
[
keycache
->
hash_links_used
++
];
}
}
else
else
{
{
/* Wait for a free hash link */
/* Wait for a free hash link */
struct
st_my_thread_var
*
thread
=
my_thread_var
;
struct
st_my_thread_var
*
thread
=
my_thread_var
;
KEYCACHE_DBUG_PRINT
(
"get_hash_link"
,
(
"waiting"
));
KEYCACHE_DBUG_PRINT
(
"get_hash_link"
,
(
"waiting"
));
page
.
file
=
file
;
page
.
filepos
=
filepos
;
page
.
file
=
file
;
page
.
filepos
=
filepos
;
thread
->
opt_info
=
(
void
*
)
&
page
;
thread
->
opt_info
=
(
void
*
)
&
page
;
link_into_queue
(
&
waiting_for_hash_link
,
thread
);
link_into_queue
(
&
keycache
->
waiting_for_hash_link
,
thread
);
keycache_pthread_cond_wait
(
&
thread
->
suspend
,
&
THR_LOCK_keycache
);
keycache_pthread_cond_wait
(
&
thread
->
suspend
,
thread
->
opt_info
=
NULL
;
&
keycache
->
thr_lock_keycache
);
thread
->
opt_info
=
NULL
;
goto
restart
;
goto
restart
;
}
}
hash_link
->
file
=
file
;
hash_link
->
file
=
file
;
hash_link
->
diskpos
=
filepos
;
hash_link
->
diskpos
=
filepos
;
link_hash
(
start
,
hash_link
);
link_hash
(
start
,
hash_link
);
}
}
/* Register the request for the page */
/* Register the request for the page */
...
@@ -870,12 +917,13 @@ restart:
...
@@ -870,12 +917,13 @@ restart:
return the lru block after saving its buffer if the page is dirty
return the lru block after saving its buffer if the page is dirty
*/
*/
static
BLOCK_LINK
*
find_key_block
(
int
file
,
my_off_t
filepos
,
static
BLOCK_LINK
*
find_key_block
(
KEY_CACHE
*
keycache
,
int
file
,
my_off_t
filepos
,
int
wrmode
,
int
*
page_st
)
int
wrmode
,
int
*
page_st
)
{
{
HASH_LINK
*
hash_link
;
HASH_LINK
*
hash_link
;
BLOCK_LINK
*
block
;
BLOCK_LINK
*
block
;
int
error
=
0
;
int
error
=
0
;
int
page_status
;
int
page_status
;
DBUG_ENTER
(
"find_key_block"
);
DBUG_ENTER
(
"find_key_block"
);
...
@@ -885,17 +933,18 @@ static BLOCK_LINK *find_key_block(int file, my_off_t filepos,
...
@@ -885,17 +933,18 @@ static BLOCK_LINK *find_key_block(int file, my_off_t filepos,
KEYCACHE_DBUG_PRINT
(
"find_key_block"
,
(
"file %u, filepos %lu, wrmode %lu"
,
KEYCACHE_DBUG_PRINT
(
"find_key_block"
,
(
"file %u, filepos %lu, wrmode %lu"
,
(
uint
)
file
,(
ulong
)
filepos
,(
uint
)
wrmode
));
(
uint
)
file
,(
ulong
)
filepos
,(
uint
)
wrmode
));
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
DBUG_EXECUTE
(
"check_keycache2"
,
test_key_cache
(
"start of find_key_block"
,
0
););
DBUG_EXECUTE
(
"check_keycache2"
,
test_key_cache
(
keycache
,
"start of find_key_block"
,
0
););
#endif
#endif
restart:
restart:
/* Find the hash link for the requested page (file, filepos) */
/* Find the hash link for the requested page (file, filepos) */
hash_link
=
get_hash_link
(
file
,
filepos
);
hash_link
=
get_hash_link
(
keycache
,
file
,
filepos
);
page_status
=-
1
;
page_status
=
-
1
;
if
((
block
=
hash_link
->
block
)
&&
if
((
block
=
hash_link
->
block
)
&&
block
->
hash_link
==
hash_link
&&
(
block
->
status
&
BLOCK_READ
))
block
->
hash_link
==
hash_link
&&
(
block
->
status
&
BLOCK_READ
))
page_status
=
PAGE_READ
;
page_status
=
PAGE_READ
;
if
(
page_status
==
PAGE_READ
&&
(
block
->
status
&
BLOCK_IN_SWITCH
))
if
(
page_status
==
PAGE_READ
&&
(
block
->
status
&
BLOCK_IN_SWITCH
))
{
{
...
@@ -907,7 +956,7 @@ restart:
...
@@ -907,7 +956,7 @@ restart:
all others are to be suspended, then resubmitted
all others are to be suspended, then resubmitted
*/
*/
if
(
!
wrmode
&&
!
(
block
->
status
&
BLOCK_REASSIGNED
))
if
(
!
wrmode
&&
!
(
block
->
status
&
BLOCK_REASSIGNED
))
reg_requests
(
block
,
1
);
reg_requests
(
keycache
,
block
,
1
);
else
else
{
{
hash_link
->
requests
--
;
hash_link
->
requests
--
;
...
@@ -920,7 +969,8 @@ restart:
...
@@ -920,7 +969,8 @@ restart:
/* Wait until the request can be resubmitted */
/* Wait until the request can be resubmitted */
do
do
{
{
keycache_pthread_cond_wait
(
&
thread
->
suspend
,
&
THR_LOCK_keycache
);
keycache_pthread_cond_wait
(
&
thread
->
suspend
,
&
keycache
->
thr_lock_keycache
);
}
}
while
(
thread
->
next
);
while
(
thread
->
next
);
}
}
...
@@ -936,23 +986,24 @@ restart:
...
@@ -936,23 +986,24 @@ restart:
if
(
!
block
)
if
(
!
block
)
{
{
/* No block is assigned for the page yet */
/* No block is assigned for the page yet */
if
(
my_blocks_used
<
(
uint
)
my_
disk_blocks
)
if
(
keycache
->
blocks_used
<
(
uint
)
keycache
->
disk_blocks
)
{
{
/* There are some never used blocks, take first of them */
/* There are some never used blocks, take first of them */
hash_link
->
block
=
block
=
&
my_block_root
[
my_blocks_used
];
hash_link
->
block
=
block
=
&
keycache
->
block_root
[
keycache
->
blocks_used
];
block
->
buffer
=
ADD_TO_PTR
(
my_block_mem
,
block
->
buffer
=
ADD_TO_PTR
(
keycache
->
block_mem
,
((
ulong
)
my_blocks_used
*
key_cache_block_size
),
((
ulong
)
keycache
->
blocks_used
*
byte
*
);
keycache
->
key_cache_block_size
),
block
->
status
=
0
;
byte
*
);
block
->
length
=
0
;
block
->
status
=
0
;
block
->
offset
=
key_cache_block_size
;
block
->
length
=
0
;
block
->
requests
=
1
;
block
->
offset
=
keycache
->
key_cache_block_size
;
my_blocks_used
++
;
block
->
requests
=
1
;
link_to_file_list
(
block
,
file
,
0
);
keycache
->
blocks_used
++
;
block
->
hash_link
=
hash_link
;
link_to_file_list
(
keycache
,
block
,
file
,
0
);
page_status
=
PAGE_TO_BE_READ
;
block
->
hash_link
=
hash_link
;
page_status
=
PAGE_TO_BE_READ
;
KEYCACHE_DBUG_PRINT
(
"find_key_block"
,
KEYCACHE_DBUG_PRINT
(
"find_key_block"
,
(
"got never used block %u"
,
BLOCK_NUMBER
(
block
)));
(
"got never used block %u"
,
BLOCK_NUMBER
(
block
)));
}
}
else
else
{
{
...
@@ -963,28 +1014,29 @@ restart:
...
@@ -963,28 +1014,29 @@ restart:
all of them must get the same block
all of them must get the same block
*/
*/
if
(
!
my_
used_last
)
if
(
!
keycache
->
used_last
)
{
{
struct
st_my_thread_var
*
thread
=
my_thread_var
;
struct
st_my_thread_var
*
thread
=
my_thread_var
;
thread
->
opt_info
=
(
void
*
)
hash_link
;
thread
->
opt_info
=
(
void
*
)
hash_link
;
link_into_queue
(
&
waiting_for_block
,
thread
);
link_into_queue
(
&
keycache
->
waiting_for_block
,
thread
);
do
do
{
{
keycache_pthread_cond_wait
(
&
thread
->
suspend
,
&
THR_LOCK_keycache
);
keycache_pthread_cond_wait
(
&
thread
->
suspend
,
&
keycache
->
thr_lock_keycache
);
}
}
while
(
thread
->
next
);
while
(
thread
->
next
);
thread
->
opt_info
=
NULL
;
thread
->
opt_info
=
NULL
;
}
}
block
=
hash_link
->
block
;
block
=
hash_link
->
block
;
if
(
!
block
)
if
(
!
block
)
{
{
/*
/*
Take the first block from the LRU chain
Take the first block from the LRU chain
unlinking it from the chain
unlinking it from the chain
*/
*/
block
=
my_
used_last
->
next_used
;
block
=
keycache
->
used_last
->
next_used
;
reg_requests
(
block
,
1
);
reg_requests
(
keycache
,
block
,
1
);
hash_link
->
block
=
block
;
hash_link
->
block
=
block
;
}
}
if
(
block
->
hash_link
!=
hash_link
&&
if
(
block
->
hash_link
!=
hash_link
&&
...
@@ -994,27 +1046,27 @@ restart:
...
@@ -994,27 +1046,27 @@ restart:
block
->
status
|=
BLOCK_IN_SWITCH
;
block
->
status
|=
BLOCK_IN_SWITCH
;
KEYCACHE_DBUG_PRINT
(
"find_key_block"
,
KEYCACHE_DBUG_PRINT
(
"find_key_block"
,
(
"got block %u for new page"
,
BLOCK_NUMBER
(
block
)));
(
"got block %u for new page"
,
BLOCK_NUMBER
(
block
)));
if
(
block
->
status
&
BLOCK_CHANGED
)
if
(
block
->
status
&
BLOCK_CHANGED
)
{
{
/* The block contains a dirty page - push it out of the cache */
/* The block contains a dirty page - push it out of the cache */
KEYCACHE_DBUG_PRINT
(
"find_key_block"
,(
"block is dirty"
));
KEYCACHE_DBUG_PRINT
(
"find_key_block"
,
(
"block is dirty"
));
keycache_pthread_mutex_unlock
(
&
THR_LOCK
_keycache
);
keycache_pthread_mutex_unlock
(
&
keycache
->
thr_lock
_keycache
);
/*
/*
The call is thread safe because only the current
The call is thread safe because only the current
thread might change the block->hash_link value
thread might change the block->hash_link value
*/
*/
error
=
my_pwrite
(
block
->
hash_link
->
file
,
block
->
buffer
,
error
=
my_pwrite
(
block
->
hash_link
->
file
,
block
->
buffer
,
block
->
length
,
block
->
hash_link
->
diskpos
,
block
->
length
,
block
->
hash_link
->
diskpos
,
MYF
(
MY_NABP
|
MY_WAIT_IF_FULL
));
MYF
(
MY_NABP
|
MY_WAIT_IF_FULL
));
keycache_pthread_mutex_lock
(
&
THR_LOCK
_keycache
);
keycache_pthread_mutex_lock
(
&
keycache
->
thr_lock
_keycache
);
my_
cache_write
++
;
keycache
->
cache_write
++
;
}
}
block
->
status
|=
BLOCK_REASSIGNED
;
block
->
status
|=
BLOCK_REASSIGNED
;
if
(
block
->
hash_link
)
if
(
block
->
hash_link
)
{
{
/*
/*
...
@@ -1023,20 +1075,21 @@ restart:
...
@@ -1023,20 +1075,21 @@ restart:
(we could have avoided this waiting, if we had read
(we could have avoided this waiting, if we had read
a page in the cache in a sweep, without yielding control)
a page in the cache in a sweep, without yielding control)
*/
*/
wait_for_readers
(
block
);
wait_for_readers
(
keycache
,
block
);
/* Remove the hash link for this page from the hash table */
/* Remove the hash link for this page from the hash table */
unlink_hash
(
block
->
hash_link
);
unlink_hash
(
keycache
,
block
->
hash_link
);
/* All pending requests for this page must be resubmitted */
/* All pending requests for this page must be resubmitted */
if
(
block
->
wqueue
[
COND_FOR_SAVED
].
last_thread
)
if
(
block
->
wqueue
[
COND_FOR_SAVED
].
last_thread
)
release_queue
(
&
block
->
wqueue
[
COND_FOR_SAVED
]);
release_queue
(
&
block
->
wqueue
[
COND_FOR_SAVED
]);
}
}
link_to_file_list
(
block
,
file
,
(
my_bool
)(
block
->
hash_link
?
1
:
0
));
link_to_file_list
(
keycache
,
block
,
file
,
block
->
status
=
error
?
BLOCK_ERROR
:
0
;
(
my_bool
)(
block
->
hash_link
?
1
:
0
));
block
->
length
=
0
;
block
->
status
=
error
?
BLOCK_ERROR
:
0
;
block
->
offset
=
key_cache_block_size
;
block
->
length
=
0
;
block
->
hash_link
=
hash_link
;
block
->
offset
=
keycache
->
key_cache_block_size
;
page_status
=
PAGE_TO_BE_READ
;
block
->
hash_link
=
hash_link
;
page_status
=
PAGE_TO_BE_READ
;
KEYCACHE_DBUG_ASSERT
(
block
->
hash_link
->
block
==
block
);
KEYCACHE_DBUG_ASSERT
(
block
->
hash_link
->
block
==
block
);
KEYCACHE_DBUG_ASSERT
(
hash_link
->
block
->
hash_link
==
hash_link
);
KEYCACHE_DBUG_ASSERT
(
hash_link
->
block
->
hash_link
==
hash_link
);
...
@@ -1044,17 +1097,17 @@ restart:
...
@@ -1044,17 +1097,17 @@ restart:
else
else
{
{
/* This is for secondary requests for a new page only */
/* This is for secondary requests for a new page only */
page_status
=
block
->
hash_link
==
hash_link
&&
page_status
=
block
->
hash_link
==
hash_link
&&
(
block
->
status
&
BLOCK_READ
)
?
(
block
->
status
&
BLOCK_READ
)
?
PAGE_READ
:
PAGE_WAIT_TO_BE_READ
;
PAGE_READ
:
PAGE_WAIT_TO_BE_READ
;
}
}
}
}
my_
cache_read
++
;
keycache
->
cache_read
++
;
}
}
else
else
{
{
reg_requests
(
block
,
1
);
reg_requests
(
keycache
,
block
,
1
);
page_status
=
block
->
hash_link
==
hash_link
&&
page_status
=
block
->
hash_link
==
hash_link
&&
(
block
->
status
&
BLOCK_READ
)
?
(
block
->
status
&
BLOCK_READ
)
?
PAGE_READ
:
PAGE_WAIT_TO_BE_READ
;
PAGE_READ
:
PAGE_WAIT_TO_BE_READ
;
...
@@ -1068,7 +1121,8 @@ restart:
...
@@ -1068,7 +1121,8 @@ restart:
(
uint
)
file
,(
ulong
)
filepos
,(
uint
)
page_status
));
(
uint
)
file
,(
ulong
)
filepos
,(
uint
)
page_status
));
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
DBUG_EXECUTE
(
"check_keycache2"
,
test_key_cache
(
"end of find_key_block"
,
0
););
DBUG_EXECUTE
(
"check_keycache2"
,
test_key_cache
(
keycache
,
"end of find_key_block"
,
0
););
#endif
#endif
KEYCACHE_THREAD_TRACE
(
"find_key_block:end"
);
KEYCACHE_THREAD_TRACE
(
"find_key_block:end"
);
DBUG_RETURN
(
block
);
DBUG_RETURN
(
block
);
...
@@ -1081,7 +1135,8 @@ restart:
...
@@ -1081,7 +1135,8 @@ restart:
portion is less than read_length, but not less than min_length
portion is less than read_length, but not less than min_length
*/
*/
static
void
read_block
(
BLOCK_LINK
*
block
,
uint
read_length
,
static
void
read_block
(
KEY_CACHE
*
keycache
,
BLOCK_LINK
*
block
,
uint
read_length
,
uint
min_length
,
my_bool
primary
)
uint
min_length
,
my_bool
primary
)
{
{
uint
got_length
;
uint
got_length
;
...
@@ -1100,16 +1155,16 @@ static void read_block(BLOCK_LINK *block, uint read_length,
...
@@ -1100,16 +1155,16 @@ static void read_block(BLOCK_LINK *block, uint read_length,
(
"page to be read by primary request"
));
(
"page to be read by primary request"
));
/* Page is not in buffer yet, is to be read from disk */
/* Page is not in buffer yet, is to be read from disk */
keycache_pthread_mutex_unlock
(
&
THR_LOCK
_keycache
);
keycache_pthread_mutex_unlock
(
&
keycache
->
thr_lock
_keycache
);
got_length
=
my_pread
(
block
->
hash_link
->
file
,
block
->
buffer
,
got_length
=
my_pread
(
block
->
hash_link
->
file
,
block
->
buffer
,
read_length
,
block
->
hash_link
->
diskpos
,
MYF
(
0
));
read_length
,
block
->
hash_link
->
diskpos
,
MYF
(
0
));
keycache_pthread_mutex_lock
(
&
THR_LOCK
_keycache
);
keycache_pthread_mutex_lock
(
&
keycache
->
thr_lock
_keycache
);
if
(
got_length
<
min_length
)
if
(
got_length
<
min_length
)
block
->
status
|=
BLOCK_ERROR
;
block
->
status
|=
BLOCK_ERROR
;
else
else
{
{
block
->
status
=
BLOCK_READ
;
block
->
status
=
BLOCK_READ
;
block
->
length
=
got_length
;
block
->
length
=
got_length
;
}
}
KEYCACHE_DBUG_PRINT
(
"read_block"
,
KEYCACHE_DBUG_PRINT
(
"read_block"
,
(
"primary request: new page in cache"
));
(
"primary request: new page in cache"
));
...
@@ -1128,10 +1183,11 @@ static void read_block(BLOCK_LINK *block, uint read_length,
...
@@ -1128,10 +1183,11 @@ static void read_block(BLOCK_LINK *block, uint read_length,
{
{
struct
st_my_thread_var
*
thread
=
my_thread_var
;
struct
st_my_thread_var
*
thread
=
my_thread_var
;
/* Put the request into a queue and wait until it can be processed */
/* Put the request into a queue and wait until it can be processed */
add_to_queue
(
&
block
->
wqueue
[
COND_FOR_REQUESTED
],
thread
);
add_to_queue
(
&
block
->
wqueue
[
COND_FOR_REQUESTED
],
thread
);
do
do
{
{
keycache_pthread_cond_wait
(
&
thread
->
suspend
,
&
THR_LOCK_keycache
);
keycache_pthread_cond_wait
(
&
thread
->
suspend
,
&
keycache
->
thr_lock_keycache
);
}
}
while
(
thread
->
next
);
while
(
thread
->
next
);
}
}
...
@@ -1150,27 +1206,29 @@ static void read_block(BLOCK_LINK *block, uint read_length,
...
@@ -1150,27 +1206,29 @@ static void read_block(BLOCK_LINK *block, uint read_length,
returns adress from where data is read
returns adress from where data is read
*/
*/
byte
*
key_cache_read
(
File
file
,
my_off_t
filepos
,
byte
*
buff
,
uint
length
,
byte
*
key_cache_read
(
void
*
pkeycache
,
File
file
,
my_off_t
filepos
,
byte
*
buff
,
uint
length
,
uint
block_length
__attribute__
((
unused
)),
uint
block_length
__attribute__
((
unused
)),
int
return_buffer
__attribute__
((
unused
)))
int
return_buffer
__attribute__
((
unused
)))
{
{
int
error
=
0
;
int
error
=
0
;
KEY_CACHE
*
keycache
=
(
KEY_CACHE
*
)
pkeycache
;
DBUG_ENTER
(
"key_cache_read"
);
DBUG_ENTER
(
"key_cache_read"
);
DBUG_PRINT
(
"enter"
,
(
"file %u, filepos %lu, length %u"
,
DBUG_PRINT
(
"enter"
,
(
"file %u, filepos %lu, length %u"
,
(
uint
)
file
,(
ulong
)
filepos
,
length
));
(
uint
)
file
,(
ulong
)
filepos
,
length
));
if
(
my_
disk_blocks
>
0
)
if
(
keycache
->
disk_blocks
>
0
)
{
{
/* Key cache is used */
/* Key cache is used */
reg1
BLOCK_LINK
*
block
;
reg1
BLOCK_LINK
*
block
;
uint
offset
=
(
uint
)
(
filepos
&
(
key_cache_block_size
-
1
));
uint
offset
=
(
uint
)
(
filepos
&
(
key
cache
->
key
_cache_block_size
-
1
));
byte
*
start
=
buff
;
byte
*
start
=
buff
;
uint
read_length
;
uint
read_length
;
uint
status
;
uint
status
;
int
page_st
;
int
page_st
;
#ifndef THREAD
#ifndef THREAD
if
(
block_length
>
key_cache_block_size
||
offset
)
if
(
block_length
>
key
cache
->
key
_cache_block_size
||
offset
)
return_buffer
=
0
;
return_buffer
=
0
;
#endif
#endif
...
@@ -1178,16 +1236,17 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
...
@@ -1178,16 +1236,17 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
filepos
-=
offset
;
filepos
-=
offset
;
do
do
{
{
read_length
=
length
>
key_cache_block_size
?
read_length
=
length
>
key
cache
->
key
_cache_block_size
?
key_cache_block_size
:
length
;
key
cache
->
key
_cache_block_size
:
length
;
KEYCACHE_DBUG_ASSERT
(
read_length
>
0
);
KEYCACHE_DBUG_ASSERT
(
read_length
>
0
);
keycache_pthread_mutex_lock
(
&
THR_LOCK
_keycache
);
keycache_pthread_mutex_lock
(
&
keycache
->
thr_lock
_keycache
);
my_
cache_r_requests
++
;
keycache
->
cache_r_requests
++
;
block
=
find_key_block
(
file
,
filepos
,
0
,
&
page_st
);
block
=
find_key_block
(
keycache
,
file
,
filepos
,
0
,
&
page_st
);
if
(
block
->
status
!=
BLOCK_ERROR
&&
page_st
!=
PAGE_READ
)
if
(
block
->
status
!=
BLOCK_ERROR
&&
page_st
!=
PAGE_READ
)
{
{
/* The requested page is to be read into the block buffer */
/* The requested page is to be read into the block buffer */
read_block
(
block
,
key_cache_block_size
,
read_length
+
offset
,
read_block
(
keycache
,
block
,
keycache
->
key_cache_block_size
,
read_length
+
offset
,
(
my_bool
)(
page_st
==
PAGE_TO_BE_READ
));
(
my_bool
)(
page_st
==
PAGE_TO_BE_READ
));
}
}
else
if
(
!
(
block
->
status
&
BLOCK_ERROR
)
&&
else
if
(
!
(
block
->
status
&
BLOCK_ERROR
)
&&
...
@@ -1198,28 +1257,28 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
...
@@ -1198,28 +1257,28 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
this could only happen if we are using a file with
this could only happen if we are using a file with
small key blocks and are trying to read outside the file
small key blocks and are trying to read outside the file
*/
*/
my_errno
=-
1
;
my_errno
=
-
1
;
block
->
status
|=
BLOCK_ERROR
;
block
->
status
|=
BLOCK_ERROR
;
}
}
if
(
!
((
status
=
block
->
status
)
&
BLOCK_ERROR
))
if
(
!
((
status
=
block
->
status
)
&
BLOCK_ERROR
))
{
{
#ifndef THREAD
#ifndef THREAD
if
(
!
return_buffer
)
if
(
!
return_buffer
)
#endif
#endif
{
{
#if !defined(SERIALIZED_READ_FROM_CACHE)
#if !defined(SERIALIZED_READ_FROM_CACHE)
keycache_pthread_mutex_unlock
(
&
THR_LOCK
_keycache
);
keycache_pthread_mutex_unlock
(
&
keycache
->
thr_lock
_keycache
);
#endif
#endif
/* Copy data from the cache buffer */
/* Copy data from the cache buffer */
if
(
!
(
read_length
&
511
))
if
(
!
(
read_length
&
511
))
bmove512
(
buff
,
block
->
buffer
+
offset
,
read_length
);
bmove512
(
buff
,
block
->
buffer
+
offset
,
read_length
);
else
else
memcpy
(
buff
,
block
->
buffer
+
offset
,
(
size_t
)
read_length
);
memcpy
(
buff
,
block
->
buffer
+
offset
,
(
size_t
)
read_length
);
#if !defined(SERIALIZED_READ_FROM_CACHE)
#if !defined(SERIALIZED_READ_FROM_CACHE)
keycache_pthread_mutex_lock
(
&
THR_LOCK
_keycache
);
keycache_pthread_mutex_lock
(
&
keycache
->
thr_lock
_keycache
);
#endif
#endif
}
}
}
}
...
@@ -1229,9 +1288,9 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
...
@@ -1229,9 +1288,9 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
Link the block into the LRU chain
Link the block into the LRU chain
if it's the last submitted request for the block
if it's the last submitted request for the block
*/
*/
unreg_request
(
block
,
1
);
unreg_request
(
keycache
,
block
,
1
);
keycache_pthread_mutex_unlock
(
&
THR_LOCK
_keycache
);
keycache_pthread_mutex_unlock
(
&
keycache
->
thr_lock
_keycache
);
if
(
status
&
BLOCK_ERROR
)
if
(
status
&
BLOCK_ERROR
)
DBUG_RETURN
((
byte
*
)
0
);
DBUG_RETURN
((
byte
*
)
0
);
...
@@ -1241,19 +1300,21 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
...
@@ -1241,19 +1300,21 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
return
(
block
->
buffer
);
return
(
block
->
buffer
);
#endif
#endif
buff
+=
read_length
;
buff
+=
read_length
;
filepos
+=
read_length
;
filepos
+=
read_length
;
offset
=
0
;
offset
=
0
;
}
while
((
length
-=
read_length
));
}
while
((
length
-=
read_length
));
DBUG_RETURN
(
start
);
DBUG_RETURN
(
start
);
}
}
/* Key cache is not used */
/* Key cache is not used */
statistic_increment
(
my_cache_r_requests
,
&
THR_LOCK_keycache
);
statistic_increment
(
keycache
->
cache_r_requests
,
statistic_increment
(
my_cache_read
,
&
THR_LOCK_keycache
);
&
keycache
->
thr_lock_keycache
);
if
(
my_pread
(
file
,(
byte
*
)
buff
,
length
,
filepos
,
MYF
(
MY_NABP
)))
statistic_increment
(
keycache
->
cache_read
,
error
=
1
;
&
keycache
->
thr_lock_keycache
);
if
(
my_pread
(
file
,
(
byte
*
)
buff
,
length
,
filepos
,
MYF
(
MY_NABP
)))
error
=
1
;
DBUG_RETURN
(
error
?
(
byte
*
)
0
:
buff
);
DBUG_RETURN
(
error
?
(
byte
*
)
0
:
buff
);
}
}
...
@@ -1272,17 +1333,19 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
...
@@ -1272,17 +1333,19 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
0 if a success, 1 -otherwise.
0 if a success, 1 -otherwise.
*/
*/
int
key_cache_insert
(
File
file
,
my_off_t
filepos
,
byte
*
buff
,
uint
length
)
int
key_cache_insert
(
void
*
pkeycache
,
File
file
,
my_off_t
filepos
,
byte
*
buff
,
uint
length
)
{
{
KEY_CACHE
*
keycache
=
(
KEY_CACHE
*
)
pkeycache
;
DBUG_ENTER
(
"key_cache_insert"
);
DBUG_ENTER
(
"key_cache_insert"
);
DBUG_PRINT
(
"enter"
,
(
"file %u, filepos %lu, length %u"
,
DBUG_PRINT
(
"enter"
,
(
"file %u, filepos %lu, length %u"
,
(
uint
)
file
,(
ulong
)
filepos
,
length
));
(
uint
)
file
,(
ulong
)
filepos
,
length
));
if
(
my_
disk_blocks
>
0
)
if
(
keycache
->
disk_blocks
>
0
)
{
{
/* Key cache is used */
/* Key cache is used */
reg1
BLOCK_LINK
*
block
;
reg1
BLOCK_LINK
*
block
;
uint
offset
=
(
uint
)
(
filepos
&
(
key_cache_block_size
-
1
));
uint
offset
=
(
uint
)
(
filepos
&
(
key
cache
->
key
_cache_block_size
-
1
));
uint
read_length
;
uint
read_length
;
int
page_st
;
int
page_st
;
...
@@ -1290,17 +1353,17 @@ int key_cache_insert(File file, my_off_t filepos, byte *buff, uint length)
...
@@ -1290,17 +1353,17 @@ int key_cache_insert(File file, my_off_t filepos, byte *buff, uint length)
filepos
-=
offset
;
filepos
-=
offset
;
do
do
{
{
read_length
=
length
>
key_cache_block_size
?
read_length
=
length
>
key
cache
->
key
_cache_block_size
?
key_cache_block_size
:
length
;
key
cache
->
key
_cache_block_size
:
length
;
KEYCACHE_DBUG_ASSERT
(
read_length
>
0
);
KEYCACHE_DBUG_ASSERT
(
read_length
>
0
);
keycache_pthread_mutex_lock
(
&
THR_LOCK
_keycache
);
keycache_pthread_mutex_lock
(
&
keycache
->
thr_lock
_keycache
);
my_
cache_r_requests
++
;
keycache
->
cache_r_requests
++
;
block
=
find_key_block
(
file
,
filepos
,
0
,
&
page_st
);
block
=
find_key_block
(
keycache
,
file
,
filepos
,
0
,
&
page_st
);
if
(
block
->
status
!=
BLOCK_ERROR
&&
page_st
!=
PAGE_READ
)
if
(
block
->
status
!=
BLOCK_ERROR
&&
page_st
!=
PAGE_READ
)
{
{
/* The requested page is to be read into the block buffer */
/* The requested page is to be read into the block buffer */
#if !defined(SERIALIZED_READ_FROM_CACHE)
#if !defined(SERIALIZED_READ_FROM_CACHE)
keycache_pthread_mutex_unlock
(
&
THR_LOCK
_keycache
);
keycache_pthread_mutex_unlock
(
&
keycache
->
thr_lock
_keycache
);
#endif
#endif
/* Copy data from buff */
/* Copy data from buff */
...
@@ -1310,7 +1373,7 @@ int key_cache_insert(File file, my_off_t filepos, byte *buff, uint length)
...
@@ -1310,7 +1373,7 @@ int key_cache_insert(File file, my_off_t filepos, byte *buff, uint length)
memcpy
(
block
->
buffer
+
offset
,
buff
,
(
size_t
)
read_length
);
memcpy
(
block
->
buffer
+
offset
,
buff
,
(
size_t
)
read_length
);
#if !defined(SERIALIZED_READ_FROM_CACHE)
#if !defined(SERIALIZED_READ_FROM_CACHE)
keycache_pthread_mutex_lock
(
&
THR_LOCK
_keycache
);
keycache_pthread_mutex_lock
(
&
keycache
->
thr_lock
_keycache
);
#endif
#endif
block
->
status
=
BLOCK_READ
;
block
->
status
=
BLOCK_READ
;
block
->
length
=
read_length
+
offset
;
block
->
length
=
read_length
+
offset
;
...
@@ -1321,15 +1384,15 @@ int key_cache_insert(File file, my_off_t filepos, byte *buff, uint length)
...
@@ -1321,15 +1384,15 @@ int key_cache_insert(File file, my_off_t filepos, byte *buff, uint length)
Link the block into the LRU chain
Link the block into the LRU chain
if it's the last submitted request for the block
if it's the last submitted request for the block
*/
*/
unreg_request
(
block
,
1
);
unreg_request
(
keycache
,
block
,
1
);
keycache_pthread_mutex_unlock
(
&
THR_LOCK
_keycache
);
keycache_pthread_mutex_unlock
(
&
keycache
->
thr_lock
_keycache
);
if
(
block
->
status
&
BLOCK_ERROR
)
if
(
block
->
status
&
BLOCK_ERROR
)
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
buff
+=
read_length
;
buff
+=
read_length
;
filepos
+=
read_length
;
filepos
+=
read_length
;
offset
=
0
;
offset
=
0
;
}
while
((
length
-=
read_length
));
}
while
((
length
-=
read_length
));
...
@@ -1346,92 +1409,96 @@ int key_cache_insert(File file, my_off_t filepos, byte *buff, uint length)
...
@@ -1346,92 +1409,96 @@ int key_cache_insert(File file, my_off_t filepos, byte *buff, uint length)
have been flushed from key cache before the function starts
have been flushed from key cache before the function starts
*/
*/
int
key_cache_write
(
File
file
,
my_off_t
filepos
,
byte
*
buff
,
uint
length
,
int
key_cache_write
(
void
*
pkeycache
,
File
file
,
my_off_t
filepos
,
byte
*
buff
,
uint
length
,
uint
block_length
__attribute__
((
unused
)),
uint
block_length
__attribute__
((
unused
)),
int
dont_write
)
int
dont_write
)
{
{
reg1
BLOCK_LINK
*
block
;
reg1
BLOCK_LINK
*
block
;
int
error
=
0
;
int
error
=
0
;
KEY_CACHE
*
keycache
=
(
KEY_CACHE
*
)
pkeycache
;
DBUG_ENTER
(
"key_cache_write"
);
DBUG_ENTER
(
"key_cache_write"
);
DBUG_PRINT
(
"enter"
,
(
"file %u, filepos %lu, length %u block_length %u"
,
DBUG_PRINT
(
"enter"
,
(
"file %u, filepos %lu, length %u block_length %u"
,
(
uint
)
file
,
(
ulong
)
filepos
,
length
,
block_length
));
(
uint
)
file
,
(
ulong
)
filepos
,
length
,
block_length
));
if
(
!
dont_write
)
if
(
!
dont_write
)
{
{
/* Force writing from buff into disk */
/* Force writing from buff into disk */
statistic_increment
(
my_cache_write
,
&
THR_LOCK_keycache
);
statistic_increment
(
keycache
->
cache_write
,
if
(
my_pwrite
(
file
,
buff
,
length
,
filepos
,
MYF
(
MY_NABP
|
MY_WAIT_IF_FULL
)))
&
keycache
->
thr_lock_keycache
);
if
(
my_pwrite
(
file
,
buff
,
length
,
filepos
,
MYF
(
MY_NABP
|
MY_WAIT_IF_FULL
)))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
}
}
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
DBUG_EXECUTE
(
"check_keycache"
,
test_key_cache
(
"start of key_cache_write"
,
1
););
DBUG_EXECUTE
(
"check_keycache"
,
test_key_cache
(
keycache
,
"start of key_cache_write"
,
1
););
#endif
#endif
if
(
my_
disk_blocks
>
0
)
if
(
keycache
->
disk_blocks
>
0
)
{
{
/* Key cache is used */
/* Key cache is used */
uint
read_length
;
uint
read_length
;
uint
offset
=
(
uint
)
(
filepos
&
(
key_cache_block_size
-
1
));
uint
offset
=
(
uint
)
(
filepos
&
(
key
cache
->
key
_cache_block_size
-
1
));
int
page_st
;
int
page_st
;
/* Write data in key_cache_block_size increments */
/* Write data in key_cache_block_size increments */
filepos
-=
offset
;
filepos
-=
offset
;
do
do
{
{
read_length
=
length
>
key_cache_block_size
?
read_length
=
length
>
key
cache
->
key
_cache_block_size
?
key_cache_block_size
:
length
;
key
cache
->
key
_cache_block_size
:
length
;
KEYCACHE_DBUG_ASSERT
(
read_length
>
0
);
KEYCACHE_DBUG_ASSERT
(
read_length
>
0
);
keycache_pthread_mutex_lock
(
&
THR_LOCK
_keycache
);
keycache_pthread_mutex_lock
(
&
keycache
->
thr_lock
_keycache
);
my_
cache_w_requests
++
;
keycache
->
cache_w_requests
++
;
block
=
find_key_block
(
file
,
filepos
,
1
,
&
page_st
);
block
=
find_key_block
(
keycache
,
file
,
filepos
,
1
,
&
page_st
);
if
(
block
->
status
!=
BLOCK_ERROR
&&
page_st
!=
PAGE_READ
&&
if
(
block
->
status
!=
BLOCK_ERROR
&&
page_st
!=
PAGE_READ
&&
(
offset
||
read_length
<
key_cache_block_size
))
(
offset
||
read_length
<
key
cache
->
key
_cache_block_size
))
read_block
(
block
,
read_block
(
keycache
,
block
,
offset
+
read_length
>=
key_cache_block_size
?
offset
+
read_length
>=
key
cache
->
key
_cache_block_size
?
offset
:
key_cache_block_size
,
offset
:
key
cache
->
key
_cache_block_size
,
offset
,(
my_bool
)(
page_st
==
PAGE_TO_BE_READ
));
offset
,(
my_bool
)(
page_st
==
PAGE_TO_BE_READ
));
if
(
!
dont_write
)
if
(
!
dont_write
)
{
{
/* buff has been written to disk at start */
/* buff has been written to disk at start */
if
((
block
->
status
&
BLOCK_CHANGED
)
&&
if
((
block
->
status
&
BLOCK_CHANGED
)
&&
(
!
offset
&&
read_length
>=
key_cache_block_size
))
(
!
offset
&&
read_length
>=
key
cache
->
key
_cache_block_size
))
link_to_file_list
(
block
,
block
->
hash_link
->
file
,
1
);
link_to_file_list
(
keycache
,
block
,
block
->
hash_link
->
file
,
1
);
}
}
else
if
(
!
(
block
->
status
&
BLOCK_CHANGED
))
else
if
(
!
(
block
->
status
&
BLOCK_CHANGED
))
link_to_changed_list
(
block
);
link_to_changed_list
(
keycache
,
block
);
set_if_smaller
(
block
->
offset
,
offset
)
set_if_smaller
(
block
->
offset
,
offset
)
set_if_bigger
(
block
->
length
,
read_length
+
offset
);
set_if_bigger
(
block
->
length
,
read_length
+
offset
);
if
(
!
(
block
->
status
&
BLOCK_ERROR
))
if
(
!
(
block
->
status
&
BLOCK_ERROR
))
{
{
if
(
!
(
read_length
&
511
))
if
(
!
(
read_length
&
511
))
bmove512
(
block
->
buffer
+
offset
,
buff
,
read_length
);
bmove512
(
block
->
buffer
+
offset
,
buff
,
read_length
);
else
else
memcpy
(
block
->
buffer
+
offset
,
buff
,
(
size_t
)
read_length
);
memcpy
(
block
->
buffer
+
offset
,
buff
,
(
size_t
)
read_length
);
}
}
block
->
status
|=
BLOCK_READ
;
block
->
status
|=
BLOCK_READ
;
/* Unregister the request */
/* Unregister the request */
block
->
hash_link
->
requests
--
;
block
->
hash_link
->
requests
--
;
unreg_request
(
block
,
1
);
unreg_request
(
keycache
,
block
,
1
);
if
(
block
->
status
&
BLOCK_ERROR
)
if
(
block
->
status
&
BLOCK_ERROR
)
{
{
keycache_pthread_mutex_unlock
(
&
THR_LOCK
_keycache
);
keycache_pthread_mutex_unlock
(
&
keycache
->
thr_lock
_keycache
);
error
=
1
;
error
=
1
;
break
;
break
;
}
}
keycache_pthread_mutex_unlock
(
&
THR_LOCK
_keycache
);
keycache_pthread_mutex_unlock
(
&
keycache
->
thr_lock
_keycache
);
buff
+=
read_length
;
buff
+=
read_length
;
filepos
+=
read_length
;
filepos
+=
read_length
;
offset
=
0
;
offset
=
0
;
}
while
((
length
-=
read_length
));
}
while
((
length
-=
read_length
));
}
}
...
@@ -1440,15 +1507,19 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
...
@@ -1440,15 +1507,19 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
/* Key cache is not used */
/* Key cache is not used */
if
(
dont_write
)
if
(
dont_write
)
{
{
statistic_increment
(
my_cache_w_requests
,
&
THR_LOCK_keycache
);
statistic_increment
(
keycache
->
cache_w_requests
,
statistic_increment
(
my_cache_write
,
&
THR_LOCK_keycache
);
&
keycache
->
thr_lock_keycache
);
if
(
my_pwrite
(
file
,(
byte
*
)
buff
,
length
,
filepos
,
MYF
(
MY_NABP
|
MY_WAIT_IF_FULL
)))
statistic_increment
(
keycache
->
cache_write
,
&
keycache
->
thr_lock_keycache
);
if
(
my_pwrite
(
file
,
(
byte
*
)
buff
,
length
,
filepos
,
MYF
(
MY_NABP
|
MY_WAIT_IF_FULL
)))
error
=
1
;
error
=
1
;
}
}
}
}
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
DBUG_EXECUTE
(
"exec"
,
test_key_cache
(
"end of key_cache_write"
,
1
););
DBUG_EXECUTE
(
"exec"
,
test_key_cache
(
keycache
,
"end of key_cache_write"
,
1
););
#endif
#endif
DBUG_RETURN
(
error
);
DBUG_RETURN
(
error
);
}
}
...
@@ -1460,27 +1531,27 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
...
@@ -1460,27 +1531,27 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
and add it at the beginning of the LRU chain
and add it at the beginning of the LRU chain
*/
*/
static
void
free_block
(
BLOCK_LINK
*
block
)
static
void
free_block
(
KEY_CACHE
*
keycache
,
BLOCK_LINK
*
block
)
{
{
KEYCACHE_THREAD_TRACE
(
"free block"
);
KEYCACHE_THREAD_TRACE
(
"free block"
);
KEYCACHE_DBUG_PRINT
(
"free_block"
,
KEYCACHE_DBUG_PRINT
(
"free_block"
,
(
"block %u to be freed"
,
BLOCK_NUMBER
(
block
)));
(
"block %u to be freed"
,
BLOCK_NUMBER
(
block
)));
if
(
block
->
hash_link
)
if
(
block
->
hash_link
)
{
{
block
->
status
|=
BLOCK_REASSIGNED
;
block
->
status
|=
BLOCK_REASSIGNED
;
wait_for_readers
(
block
);
wait_for_readers
(
keycache
,
block
);
unlink_hash
(
block
->
hash_link
);
unlink_hash
(
keycache
,
block
->
hash_link
);
}
}
unlink_changed
(
block
);
unlink_changed
(
block
);
block
->
status
=
0
;
block
->
status
=
0
;
block
->
length
=
0
;
block
->
length
=
0
;
block
->
offset
=
key_cache_block_size
;
block
->
offset
=
keycache
->
key_cache_block_size
;
KEYCACHE_THREAD_TRACE
(
"free block"
);
KEYCACHE_THREAD_TRACE
(
"free block"
);
KEYCACHE_DBUG_PRINT
(
"free_block"
,
KEYCACHE_DBUG_PRINT
(
"free_block"
,
(
"block is freed"
));
(
"block is freed"
));
unreg_request
(
block
,
0
);
unreg_request
(
keycache
,
block
,
0
);
block
->
hash_link
=
NULL
;
block
->
hash_link
=
NULL
;
}
}
...
@@ -1496,51 +1567,53 @@ static int cmp_sec_link(BLOCK_LINK **a, BLOCK_LINK **b)
...
@@ -1496,51 +1567,53 @@ static int cmp_sec_link(BLOCK_LINK **a, BLOCK_LINK **b)
free used blocks if requested
free used blocks if requested
*/
*/
static
int
flush_cached_blocks
(
File
file
,
BLOCK_LINK
**
cache
,
static
int
flush_cached_blocks
(
KEY_CACHE
*
keycache
,
File
file
,
BLOCK_LINK
**
cache
,
BLOCK_LINK
**
end
,
BLOCK_LINK
**
end
,
enum
flush_type
type
)
enum
flush_type
type
)
{
{
int
error
;
int
error
;
int
last_errno
=
0
;
int
last_errno
=
0
;
uint
count
=
end
-
cache
;
uint
count
=
end
-
cache
;
/* Don't lock the cache during the flush */
/* Don't lock the cache during the flush */
keycache_pthread_mutex_unlock
(
&
THR_LOCK
_keycache
);
keycache_pthread_mutex_unlock
(
&
keycache
->
thr_lock
_keycache
);
/*
/*
As all blocks referred in 'cache' are marked by BLOCK_IN_FLUSH
As all blocks referred in 'cache' are marked by BLOCK_IN_FLUSH
we are guarunteed no thread will change them
we are guarunteed no thread will change them
*/
*/
qsort
((
byte
*
)
cache
,
count
,
sizeof
(
*
cache
),
(
qsort_cmp
)
cmp_sec_link
);
qsort
((
byte
*
)
cache
,
count
,
sizeof
(
*
cache
),
(
qsort_cmp
)
cmp_sec_link
);
keycache_pthread_mutex_lock
(
&
THR_LOCK
_keycache
);
keycache_pthread_mutex_lock
(
&
keycache
->
thr_lock
_keycache
);
for
(
;
cache
!=
end
;
cache
++
)
for
(
;
cache
!=
end
;
cache
++
)
{
{
BLOCK_LINK
*
block
=
*
cache
;
BLOCK_LINK
*
block
=
*
cache
;
KEYCACHE_DBUG_PRINT
(
"flush_cached_blocks"
,
KEYCACHE_DBUG_PRINT
(
"flush_cached_blocks"
,
(
"block %u to be flushed"
,
BLOCK_NUMBER
(
block
)));
(
"block %u to be flushed"
,
BLOCK_NUMBER
(
block
)));
keycache_pthread_mutex_unlock
(
&
THR_LOCK_keycache
);
keycache_pthread_mutex_unlock
(
&
keycache
->
thr_lock_keycache
);
error
=
my_pwrite
(
file
,
block
->
buffer
+
block
->
offset
,
block
->
length
,
error
=
my_pwrite
(
file
,
block
->
buffer
+
block
->
offset
,
block
->
length
,
block
->
hash_link
->
diskpos
,
MYF
(
MY_NABP
|
MY_WAIT_IF_FULL
));
block
->
hash_link
->
diskpos
,
keycache_pthread_mutex_lock
(
&
THR_LOCK_keycache
);
MYF
(
MY_NABP
|
MY_WAIT_IF_FULL
));
my_cache_write
++
;
keycache_pthread_mutex_lock
(
&
keycache
->
thr_lock_keycache
);
keycache
->
cache_write
++
;
if
(
error
)
if
(
error
)
{
{
block
->
status
|=
BLOCK_ERROR
;
block
->
status
|=
BLOCK_ERROR
;
if
(
!
last_errno
)
if
(
!
last_errno
)
last_errno
=
errno
?
errno
:
-
1
;
last_errno
=
errno
?
errno
:
-
1
;
}
}
/* type will never be FLUSH_IGNORE_CHANGED here */
/* type will never be FLUSH_IGNORE_CHANGED here */
if
(
!
(
type
==
FLUSH_KEEP
||
type
==
FLUSH_FORCE_WRITE
))
if
(
!
(
type
==
FLUSH_KEEP
||
type
==
FLUSH_FORCE_WRITE
))
{
{
my_
blocks_changed
--
;
keycache
->
blocks_changed
--
;
free_block
(
block
);
free_block
(
keycache
,
block
);
}
}
else
else
{
{
block
->
status
&=~
BLOCK_IN_FLUSH
;
block
->
status
&=
~
BLOCK_IN_FLUSH
;
link_to_file_list
(
block
,
file
,
1
);
link_to_file_list
(
keycache
,
block
,
file
,
1
);
unreg_request
(
block
,
1
);
unreg_request
(
keycache
,
block
,
1
);
}
}
}
}
...
@@ -1552,29 +1625,32 @@ static int flush_cached_blocks(File file, BLOCK_LINK **cache,
...
@@ -1552,29 +1625,32 @@ static int flush_cached_blocks(File file, BLOCK_LINK **cache,
Flush all blocks for a file to disk
Flush all blocks for a file to disk
*/
*/
int
flush_key_blocks
(
File
file
,
enum
flush_type
type
)
int
flush_key_blocks
(
void
*
pkeycache
,
File
file
,
enum
flush_type
type
)
{
{
int
last_errno
=
0
;
BLOCK_LINK
*
cache_buff
[
FLUSH_CACHE
],
**
cache
;
BLOCK_LINK
*
cache_buff
[
FLUSH_CACHE
],
**
cache
;
int
last_errno
=
0
;
KEY_CACHE
*
keycache
=
(
KEY_CACHE
*
)
pkeycache
;
DBUG_ENTER
(
"flush_key_blocks"
);
DBUG_ENTER
(
"flush_key_blocks"
);
DBUG_PRINT
(
"enter"
,(
"file: %d blocks_used: %d blocks_changed: %d"
,
DBUG_PRINT
(
"enter"
,(
"file: %d blocks_used: %d blocks_changed: %d"
,
file
,
my_blocks_used
,
my_
blocks_changed
));
file
,
keycache
->
blocks_used
,
keycache
->
blocks_changed
));
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
DBUG_EXECUTE
(
"check_keycache"
,
test_key_cache
(
"start of flush_key_blocks"
,
0
););
DBUG_EXECUTE
(
"check_keycache"
,
test_key_cache
(
keycache
,
"start of flush_key_blocks"
,
0
););
#endif
#endif
keycache_pthread_mutex_lock
(
&
THR_LOCK
_keycache
);
keycache_pthread_mutex_lock
(
&
keycache
->
thr_lock
_keycache
);
cache
=
cache_buff
;
cache
=
cache_buff
;
if
(
my_
disk_blocks
>
0
&&
if
(
keycache
->
disk_blocks
>
0
&&
(
!
my_disable_flush_key_blocks
||
type
!=
FLUSH_KEEP
))
(
!
my_disable_flush_key_blocks
||
type
!=
FLUSH_KEEP
))
{
{
/* Key cache exists and flush is not disabled */
/* Key cache exists and flush is not disabled */
int
error
=
0
;
int
error
=
0
;
uint
count
=
0
;
uint
count
=
0
;
BLOCK_LINK
**
pos
,
**
end
;
BLOCK_LINK
**
pos
,
**
end
;
BLOCK_LINK
*
first_in_switch
=
NULL
;
BLOCK_LINK
*
first_in_switch
=
NULL
;
BLOCK_LINK
*
block
,
*
next
;
BLOCK_LINK
*
block
,
*
next
;
#if defined(KEYCACHE_DEBUG)
#if defined(KEYCACHE_DEBUG)
uint
cnt
=
0
;
uint
cnt
=
0
;
...
@@ -1586,37 +1662,38 @@ int flush_key_blocks(File file, enum flush_type type)
...
@@ -1586,37 +1662,38 @@ int flush_key_blocks(File file, enum flush_type type)
Count how many key blocks we have to cache to be able
Count how many key blocks we have to cache to be able
to flush all dirty pages with minimum seek moves
to flush all dirty pages with minimum seek moves
*/
*/
for
(
block
=
changed_blocks
[
FILE_HASH
(
file
)]
;
for
(
block
=
keycache
->
changed_blocks
[
FILE_HASH
(
file
)]
;
block
;
block
;
block
=
block
->
next_changed
)
block
=
block
->
next_changed
)
{
{
if
(
block
->
hash_link
->
file
==
file
)
if
(
block
->
hash_link
->
file
==
file
)
{
{
count
++
;
count
++
;
KEYCACHE_DBUG_ASSERT
(
count
<=
my_
blocks_used
);
KEYCACHE_DBUG_ASSERT
(
count
<=
keycache
->
blocks_used
);
}
}
}
}
/* Allocate a new buffer only if its bigger than the one we have */
/* Allocate a new buffer only if its bigger than the one we have */
if
(
count
>
FLUSH_CACHE
&&
if
(
count
>
FLUSH_CACHE
&&
!
(
cache
=
(
BLOCK_LINK
**
)
my_malloc
(
sizeof
(
BLOCK_LINK
*
)
*
count
,
MYF
(
0
))))
!
(
cache
=
(
BLOCK_LINK
**
)
my_malloc
(
sizeof
(
BLOCK_LINK
*
)
*
count
,
MYF
(
0
))))
{
{
cache
=
cache_buff
;
cache
=
cache_buff
;
count
=
FLUSH_CACHE
;
count
=
FLUSH_CACHE
;
}
}
}
}
/* Retrieve the blocks and write them to a buffer to be flushed */
/* Retrieve the blocks and write them to a buffer to be flushed */
restart:
restart:
end
=
(
pos
=
cache
)
+
count
;
end
=
(
pos
=
cache
)
+
count
;
for
(
block
=
changed_blocks
[
FILE_HASH
(
file
)]
;
for
(
block
=
keycache
->
changed_blocks
[
FILE_HASH
(
file
)]
;
block
;
block
;
block
=
next
)
block
=
next
)
{
{
#if defined(KEYCACHE_DEBUG)
#if defined(KEYCACHE_DEBUG)
cnt
++
;
cnt
++
;
KEYCACHE_DBUG_ASSERT
(
cnt
<=
my_
blocks_used
);
KEYCACHE_DBUG_ASSERT
(
cnt
<=
keycache
->
blocks_used
);
#endif
#endif
next
=
block
->
next_changed
;
next
=
block
->
next_changed
;
if
(
block
->
hash_link
->
file
==
file
)
if
(
block
->
hash_link
->
file
==
file
)
{
{
/*
/*
...
@@ -1632,7 +1709,7 @@ restart:
...
@@ -1632,7 +1709,7 @@ restart:
We care only for the blocks for which flushing was not
We care only for the blocks for which flushing was not
initiated by other threads as a result of page swapping
initiated by other threads as a result of page swapping
*/
*/
reg_requests
(
block
,
1
);
reg_requests
(
keycache
,
block
,
1
);
if
(
type
!=
FLUSH_IGNORE_CHANGED
)
if
(
type
!=
FLUSH_IGNORE_CHANGED
)
{
{
/* It's not a temporary file */
/* It's not a temporary file */
...
@@ -1642,7 +1719,8 @@ restart:
...
@@ -1642,7 +1719,8 @@ restart:
This happens only if there is not enough
This happens only if there is not enough
memory for the big block
memory for the big block
*/
*/
if
((
error
=
flush_cached_blocks
(
file
,
cache
,
end
,
type
)))
if
((
error
=
flush_cached_blocks
(
keycache
,
file
,
cache
,
end
,
type
)))
last_errno
=
error
;
last_errno
=
error
;
/*
/*
Restart the scan as some other thread might have changed
Restart the scan as some other thread might have changed
...
@@ -1651,47 +1729,48 @@ restart:
...
@@ -1651,47 +1729,48 @@ restart:
*/
*/
goto
restart
;
goto
restart
;
}
}
*
pos
++=
block
;
*
pos
++=
block
;
}
}
else
else
{
{
/* It's a temporary file */
/* It's a temporary file */
my_
blocks_changed
--
;
keycache
->
blocks_changed
--
;
free_block
(
block
);
free_block
(
keycache
,
block
);
}
}
}
}
else
else
{
{
/* Link the block into a list of blocks 'in switch' */
/* Link the block into a list of blocks 'in switch' */
unlink_changed
(
block
);
unlink_changed
(
block
);
link_changed
(
block
,
&
first_in_switch
);
link_changed
(
block
,
&
first_in_switch
);
}
}
}
}
}
}
if
(
pos
!=
cache
)
if
(
pos
!=
cache
)
{
{
if
((
error
=
flush_cached_blocks
(
file
,
cache
,
pos
,
type
)))
if
((
error
=
flush_cached_blocks
(
keycache
,
file
,
cache
,
pos
,
type
)))
last_errno
=
error
;
last_errno
=
error
;
}
}
/* Wait until list of blocks in switch is empty */
/* Wait until list of blocks in switch is empty */
while
(
first_in_switch
)
while
(
first_in_switch
)
{
{
#if defined(KEYCACHE_DEBUG)
#if defined(KEYCACHE_DEBUG)
cnt
=
0
;
cnt
=
0
;
#endif
#endif
block
=
first_in_switch
;
block
=
first_in_switch
;
{
{
struct
st_my_thread_var
*
thread
=
my_thread_var
;
struct
st_my_thread_var
*
thread
=
my_thread_var
;
add_to_queue
(
&
block
->
wqueue
[
COND_FOR_SAVED
],
thread
);
add_to_queue
(
&
block
->
wqueue
[
COND_FOR_SAVED
],
thread
);
do
do
{
{
keycache_pthread_cond_wait
(
&
thread
->
suspend
,
&
THR_LOCK_keycache
);
keycache_pthread_cond_wait
(
&
thread
->
suspend
,
&
keycache
->
thr_lock_keycache
);
}
}
while
(
thread
->
next
);
while
(
thread
->
next
);
}
}
#if defined(KEYCACHE_DEBUG)
#if defined(KEYCACHE_DEBUG)
cnt
++
;
cnt
++
;
KEYCACHE_DBUG_ASSERT
(
cnt
<=
my_
blocks_used
);
KEYCACHE_DBUG_ASSERT
(
cnt
<=
keycache
->
blocks_used
);
#endif
#endif
}
}
/* The following happens very seldom */
/* The following happens very seldom */
...
@@ -1700,34 +1779,34 @@ restart:
...
@@ -1700,34 +1779,34 @@ restart:
#if defined(KEYCACHE_DEBUG)
#if defined(KEYCACHE_DEBUG)
cnt
=
0
;
cnt
=
0
;
#endif
#endif
for
(
block
=
file_blocks
[
FILE_HASH
(
file
)]
;
for
(
block
=
keycache
->
file_blocks
[
FILE_HASH
(
file
)]
;
block
;
block
;
block
=
next
)
block
=
next
)
{
{
#if defined(KEYCACHE_DEBUG)
#if defined(KEYCACHE_DEBUG)
cnt
++
;
cnt
++
;
KEYCACHE_DBUG_ASSERT
(
cnt
<=
my_
blocks_used
);
KEYCACHE_DBUG_ASSERT
(
cnt
<=
keycache
->
blocks_used
);
#endif
#endif
next
=
block
->
next_changed
;
next
=
block
->
next_changed
;
if
(
block
->
hash_link
->
file
==
file
&&
if
(
block
->
hash_link
->
file
==
file
&&
(
!
(
block
->
status
&
BLOCK_CHANGED
)
(
!
(
block
->
status
&
BLOCK_CHANGED
)
||
type
==
FLUSH_IGNORE_CHANGED
))
||
type
==
FLUSH_IGNORE_CHANGED
))
{
{
reg_requests
(
block
,
1
);
reg_requests
(
keycache
,
block
,
1
);
free_block
(
block
);
free_block
(
keycache
,
block
);
}
}
}
}
}
}
}
}
keycache_pthread_mutex_unlock
(
&
THR_LOCK
_keycache
);
keycache_pthread_mutex_unlock
(
&
keycache
->
thr_lock
_keycache
);
#ifndef DBUG_OFF
#ifndef DBUG_OFF
DBUG_EXECUTE
(
"check_keycache"
,
DBUG_EXECUTE
(
"check_keycache"
,
test_key_cache
(
"end of flush_key_blocks"
,
0
););
test_key_cache
(
keycache
,
"end of flush_key_blocks"
,
0
););
#endif
#endif
if
(
cache
!=
cache_buff
)
if
(
cache
!=
cache_buff
)
my_free
((
gptr
)
cache
,
MYF
(
0
));
my_free
((
gptr
)
cache
,
MYF
(
0
));
if
(
last_errno
)
if
(
last_errno
)
errno
=
last_errno
;
/* Return first error */
errno
=
last_errno
;
/* Return first error */
DBUG_RETURN
(
last_errno
!=
0
);
DBUG_RETURN
(
last_errno
!=
0
);
...
@@ -1738,27 +1817,27 @@ restart:
...
@@ -1738,27 +1817,27 @@ restart:
Flush all blocks in the key cache to disk
Flush all blocks in the key cache to disk
*/
*/
static
int
flush_all_key_blocks
()
static
int
flush_all_key_blocks
(
KEY_CACHE
*
keycache
)
{
{
#if defined(KEYCACHE_DEBUG)
#if defined(KEYCACHE_DEBUG)
uint
cnt
=
0
;
uint
cnt
=
0
;
#endif
#endif
while
(
my_
blocks_changed
>
0
)
while
(
keycache
->
blocks_changed
>
0
)
{
{
BLOCK_LINK
*
block
;
BLOCK_LINK
*
block
;
for
(
block
=
my_
used_last
->
next_used
;
;
block
=
block
->
next_used
)
for
(
block
=
keycache
->
used_last
->
next_used
;
;
block
=
block
->
next_used
)
{
{
if
(
block
->
hash_link
)
if
(
block
->
hash_link
)
{
{
#if defined(KEYCACHE_DEBUG)
#if defined(KEYCACHE_DEBUG)
cnt
++
;
cnt
++
;
KEYCACHE_DBUG_ASSERT
(
cnt
<=
my_
blocks_used
);
KEYCACHE_DBUG_ASSERT
(
cnt
<=
keycache
->
blocks_used
);
#endif
#endif
if
(
flush_key_blocks
(
block
->
hash_link
->
file
,
FLUSH_RELEASE
))
if
(
flush_key_blocks
(
keycache
,
block
->
hash_link
->
file
,
FLUSH_RELEASE
))
return
1
;
return
1
;
break
;
break
;
}
}
if
(
block
==
my_
used_last
)
if
(
block
==
keycache
->
used_last
)
break
;
break
;
}
}
}
}
...
@@ -1770,7 +1849,8 @@ static int flush_all_key_blocks()
...
@@ -1770,7 +1849,8 @@ static int flush_all_key_blocks()
/*
/*
Test if disk-cache is ok
Test if disk-cache is ok
*/
*/
static
void
test_key_cache
(
const
char
*
where
__attribute__
((
unused
)),
static
void
test_key_cache
(
KEY_CACHE
*
keycache
,
const
char
*
where
__attribute__
((
unused
)),
my_bool
lock
__attribute__
((
unused
)))
my_bool
lock
__attribute__
((
unused
)))
{
{
/* TODO */
/* TODO */
...
@@ -1783,10 +1863,10 @@ static void test_key_cache(const char *where __attribute__((unused)),
...
@@ -1783,10 +1863,10 @@ static void test_key_cache(const char *where __attribute__((unused)),
#define MAX_QUEUE_LEN 100
#define MAX_QUEUE_LEN 100
static
void
keycache_dump
()
static
void
keycache_dump
(
KEY_CACHE
*
keycache
)
{
{
FILE
*
keycache_dump_file
=
fopen
(
KEYCACHE_DUMP_FILE
,
"w"
);
FILE
*
keycache_dump_file
=
fopen
(
KEYCACHE_DUMP_FILE
,
"w"
);
struct
st_my_thread_var
*
thread_var
=
my_thread_var
;
struct
st_my_thread_var
*
thread_var
=
my_thread_var
;
struct
st_my_thread_var
*
last
;
struct
st_my_thread_var
*
last
;
struct
st_my_thread_var
*
thread
;
struct
st_my_thread_var
*
thread
;
BLOCK_LINK
*
block
;
BLOCK_LINK
*
block
;
...
@@ -1829,10 +1909,10 @@ static void keycache_dump()
...
@@ -1829,10 +1909,10 @@ static void keycache_dump()
}
}
while
(
thread
!=
last
);
while
(
thread
!=
last
);
for
(
i
=
0
;
i
<
my_
blocks_used
;
i
++
)
for
(
i
=
0
;
i
<
keycache
->
blocks_used
;
i
++
)
{
{
int
j
;
int
j
;
block
=
&
my_
block_root
[
i
];
block
=
&
keycache
->
block_root
[
i
];
hash_link
=
block
->
hash_link
;
hash_link
=
block
->
hash_link
;
fprintf
(
keycache_dump_file
,
fprintf
(
keycache_dump_file
,
"block:%u hash_link:%d status:%x #requests=%u waiting_for_readers:%d
\n
"
,
"block:%u hash_link:%d status:%x #requests=%u waiting_for_readers:%d
\n
"
,
...
@@ -1858,16 +1938,16 @@ static void keycache_dump()
...
@@ -1858,16 +1938,16 @@ static void keycache_dump()
}
}
}
}
fprintf
(
keycache_dump_file
,
"LRU chain:"
);
fprintf
(
keycache_dump_file
,
"LRU chain:"
);
block
=
my_
used_last
;
block
=
keycache
=
used_last
;
if
(
block
)
if
(
block
)
{
{
do
do
{
{
block
=
block
->
next_used
;
block
=
block
->
next_used
;
fprintf
(
keycache_dump_file
,
fprintf
(
keycache_dump_file
,
"block:%u, "
,
BLOCK_NUMBER
(
block
));
"block:%u, "
,
BLOCK_NUMBER
(
block
));
}
}
while
(
block
!=
my_
used_last
);
while
(
block
!=
keycache
->
used_last
);
}
}
fprintf
(
keycache_dump_file
,
"
\n
"
);
fprintf
(
keycache_dump_file
,
"
\n
"
);
...
...
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