Commit d6a868cc authored by unknown's avatar unknown

Merge desktop.sanja.is.com.ua:/home/bell/mysql/bk/mysql-maria

into  desktop.sanja.is.com.ua:/home/bell/mysql/bk/work-maria-bug34161


storage/maria/ma_pagecache.c:
  Auto merged
parents 33268ef2 cb805686
......@@ -276,7 +276,7 @@ typedef struct _db_code_state_ {
static struct link *ListAddDel(struct link *, const char *, const char *, int);
static struct link *ListCopy(struct link *);
static int InList(struct link *linkp,const char *cp);
static int ListFlags(struct link *linkp);
static uint ListFlags(struct link *linkp);
static void FreeList(struct link *linkp);
/* OpenClose debug output stream */
......@@ -738,10 +738,10 @@ void FixTraceFlags_helper(CODE_STATE *cs, const char *func,
#define fflags(cs) cs->stack->out_file ? ListFlags(cs->stack->functions) : TRACE_ON;
void FixTraceFlags(int old_fflags, CODE_STATE *cs)
void FixTraceFlags(uint old_fflags, CODE_STATE *cs)
{
const char *func;
int new_fflags, traceon, level;
uint new_fflags, traceon, level;
struct _db_stack_frame_ *framep;
/*
......@@ -831,7 +831,7 @@ void FixTraceFlags(int old_fflags, CODE_STATE *cs)
void _db_set_(const char *control)
{
CODE_STATE *cs;
int old_fflags;
uint old_fflags;
get_code_state_or_return;
old_fflags=fflags(cs);
if (ParseDbug(cs, control))
......@@ -859,7 +859,7 @@ void _db_set_(const char *control)
void _db_push_(const char *control)
{
CODE_STATE *cs;
int old_fflags;
uint old_fflags;
get_code_state_or_return;
old_fflags=fflags(cs);
PushState(cs);
......@@ -910,7 +910,7 @@ void _db_set_init_(const char *control)
void _db_pop_()
{
struct settings *discard;
int old_fflags;
uint old_fflags;
CODE_STATE *cs;
get_code_state_or_return;
......@@ -1559,9 +1559,9 @@ static int InList(struct link *linkp, const char *cp)
*
*/
static int ListFlags(struct link *linkp)
static uint ListFlags(struct link *linkp)
{
int f;
uint f;
for (f=0; linkp != NULL; linkp= linkp->next_link)
f|= linkp->flags;
return f;
......
drop table if exists t1, t2;
create table t1 (
a int not null auto_increment,
b char(16) not null,
primary key (a),
key (b)
) engine=maria row_format=dynamic;
create table t2(
a int not null auto_increment,
b char(16) not null,
primary key (a),
key (b)
) engine=maria row_format=dynamic;
insert into t1(b) values
('test0'),
('test1'),
('test2'),
('test3'),
('test4'),
('test5'),
('test6'),
('test7');
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
select count(*) from t1;
count(*)
33448
select count(*) from t2;
count(*)
20672
flush tables;
flush status;
show status like "maria_pagecache_read%";
Variable_name Value
Maria_pagecache_read_requests 211388
Maria_pagecache_reads 115
select count(*) from t1 where b = 'test1';
count(*)
4181
show status like "maria_pagecache_read%";
Variable_name Value
Maria_pagecache_read_requests 211414
Maria_pagecache_reads 122
select count(*) from t1 where b = 'test1';
count(*)
4181
show status like "maria_pagecache_read%";
Variable_name Value
Maria_pagecache_read_requests 211440
Maria_pagecache_reads 122
flush tables;
flush status;
select @@preload_buffer_size;
@@preload_buffer_size
32768
load index into cache t1;
Table Op Msg_type Msg_text
test.t1 preload_keys status OK
show status like "maria_pagecache_read%";
Variable_name Value
Maria_pagecache_read_requests 211511
Maria_pagecache_reads 193
select count(*) from t1 where b = 'test1';
count(*)
4181
show status like "maria_pagecache_read%";
Variable_name Value
Maria_pagecache_read_requests 211537
Maria_pagecache_reads 193
flush tables;
flush status;
show status like "maria_pagecache_read%";
Variable_name Value
Maria_pagecache_read_requests 211537
Maria_pagecache_reads 193
set session preload_buffer_size=256*1024;
select @@preload_buffer_size;
@@preload_buffer_size
262144
load index into cache t1 ignore leaves;
Table Op Msg_type Msg_text
test.t1 preload_keys status OK
show status like "maria_pagecache_read%";
Variable_name Value
Maria_pagecache_read_requests 211608
Maria_pagecache_reads 264
select count(*) from t1 where b = 'test1';
count(*)
4181
show status like "maria_pagecache_read%";
Variable_name Value
Maria_pagecache_read_requests 211634
Maria_pagecache_reads 270
flush tables;
flush status;
show status like "maria_pagecache_read%";
Variable_name Value
Maria_pagecache_read_requests 211634
Maria_pagecache_reads 270
set session preload_buffer_size=1*1024;
select @@preload_buffer_size;
@@preload_buffer_size
1024
load index into cache t1, t2 key (primary,b) ignore leaves;
Table Op Msg_type Msg_text
test.t1 preload_keys status OK
test.t2 preload_keys status OK
show status like "maria_pagecache_read%";
Variable_name Value
Maria_pagecache_read_requests 211748
Maria_pagecache_reads 384
select count(*) from t1 where b = 'test1';
count(*)
4181
select count(*) from t2 where b = 'test1';
count(*)
2584
show status like "maria_pagecache_read%";
Variable_name Value
Maria_pagecache_read_requests 211788
Maria_pagecache_reads 387
flush tables;
flush status;
show status like "maria_pagecache_read%";
Variable_name Value
Maria_pagecache_read_requests 211788
Maria_pagecache_reads 387
load index into cache t3, t2 key (primary,b) ;
Table Op Msg_type Msg_text
test.t3 preload_keys Error Table 'test.t3' doesn't exist
test.t3 preload_keys error Corrupt
test.t2 preload_keys status OK
show status like "maria_pagecache_read%";
Variable_name Value
Maria_pagecache_read_requests 211831
Maria_pagecache_reads 430
flush tables;
flush status;
show status like "maria_pagecache_read%";
Variable_name Value
Maria_pagecache_read_requests 211831
Maria_pagecache_reads 430
load index into cache t3 key (b), t2 key (c) ;
Table Op Msg_type Msg_text
test.t3 preload_keys Error Table 'test.t3' doesn't exist
test.t3 preload_keys error Corrupt
test.t2 preload_keys Error Key 'c' doesn't exist in table 't2'
test.t2 preload_keys status Operation failed
show status like "maria_pagecache_read%";
Variable_name Value
Maria_pagecache_read_requests 211831
Maria_pagecache_reads 430
drop table t1, t2;
show status like "key_read%";
Variable_name Value
Key_read_requests 0
Key_reads 0
......@@ -24,3 +24,4 @@ wait_timeout : Bug#32801 wait_timeout.test fails randomly
ctype_create : Bug#32965 main.ctype_create fails
status : Bug#32966 main.status fails
ps_ddl : Bug#12093 2007-12-14 pending WL#4165 / WL#4166
maria-preload : Bug#35030 unrepeatable output of SHOW STATUS
#
# Testing of PRELOAD
#
-- source include/have_maria.inc
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
# we don't use block-format because we want page cache stats
# about indices and not data pages.
create table t1 (
a int not null auto_increment,
b char(16) not null,
primary key (a),
key (b)
) engine=maria row_format=dynamic;
create table t2(
a int not null auto_increment,
b char(16) not null,
primary key (a),
key (b)
) engine=maria row_format=dynamic;
insert into t1(b) values
('test0'),
('test1'),
('test2'),
('test3'),
('test4'),
('test5'),
('test6'),
('test7');
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
insert into t2(b) select b from t1;
insert into t1(b) select b from t2;
select count(*) from t1;
select count(*) from t2;
flush tables; flush status;
show status like "maria_pagecache_read%";
select count(*) from t1 where b = 'test1';
show status like "maria_pagecache_read%";
select count(*) from t1 where b = 'test1';
show status like "maria_pagecache_read%";
flush tables; flush status;
select @@preload_buffer_size;
load index into cache t1;
show status like "maria_pagecache_read%";
select count(*) from t1 where b = 'test1';
show status like "maria_pagecache_read%";
flush tables; flush status;
show status like "maria_pagecache_read%";
set session preload_buffer_size=256*1024;
select @@preload_buffer_size;
load index into cache t1 ignore leaves;
show status like "maria_pagecache_read%";
select count(*) from t1 where b = 'test1';
show status like "maria_pagecache_read%";
flush tables; flush status;
show status like "maria_pagecache_read%";
set session preload_buffer_size=1*1024;
select @@preload_buffer_size;
load index into cache t1, t2 key (primary,b) ignore leaves;
show status like "maria_pagecache_read%";
select count(*) from t1 where b = 'test1';
select count(*) from t2 where b = 'test1';
show status like "maria_pagecache_read%";
flush tables; flush status;
show status like "maria_pagecache_read%";
load index into cache t3, t2 key (primary,b) ;
show status like "maria_pagecache_read%";
flush tables; flush status;
show status like "maria_pagecache_read%";
load index into cache t3 key (b), t2 key (c) ;
show status like "maria_pagecache_read%";
drop table t1, t2;
# check that Maria didn't use key cache
show status like "key_read%";
......@@ -23,6 +23,15 @@
}
{
pthread allocate_tls memory loss
Memcheck:Leak
fun:calloc
obj:/lib64/ld*.so
fun:_dl_allocate_tls
fun:pthread_create*
}
{
pthead_exit memory loss 1
Memcheck:Leak
......@@ -369,6 +378,41 @@
fun:_Z8udf_freev
}
{
dlopen / ptread_cancel_init memory loss on Suse Linux 10.3 64 bit
Memcheck:Leak
fun:*alloc
obj:/lib64/ld-*.so
obj:/lib64/ld-*.so
obj:/lib64/ld-*.so
obj:/lib64/ld-*.so
obj:/lib64/ld-*.so
obj:/lib64/ld-*.so
obj:/lib64/libc-*.so
obj:/lib64/ld-*.so
obj:/lib64/libc-*.so
fun:__libc_dlopen_mode
fun:pthread_cancel_init
fun:_Unwind_ForcedUnwind
}
{
dlopen / ptread_cancel_init memory loss on Suse Linux 10.3 64 bit
Memcheck:Leak
fun:*alloc
obj:/lib64/ld-*.so
obj:/lib64/ld-*.so
obj:/lib64/ld-*.so
obj:/lib64/ld-*.so
obj:/lib64/libc-*.so
obj:/lib64/ld-*.so
obj:/lib64/libc-*.so
fun:__libc_dlopen_mode
fun:pthread_cancel_init
fun:_Unwind_ForcedUnwind
}
#
# These seem to be libc threading stuff, not related to MySQL code (allocations
......
......@@ -800,7 +800,7 @@ static void close_connections(void)
break;
}
#ifdef EXTRA_DEBUG
if (error != 0 && !count++)
if (error != 0 && error != ETIMEDOUT && !count++)
sql_print_error("Got error %d from pthread_cond_timedwait",error);
#endif
close_server_sock();
......@@ -7444,18 +7444,22 @@ mysqld_get_one_option(int optid,
char *argument)
{
switch(optid) {
#ifndef DBUG_OFF
case '#':
if (*argument == '0')
if (!argument)
argument= (char*) default_dbug_option;
if (argument[0] == '0' && !argument[1])
{
DEBUGGER_OFF;
break;
}
DEBUGGER_ON;
if (*argument == '1')
if (argument[0] == '1' && !argument[1])
break;
DBUG_SET_INITIAL(argument ? argument : default_dbug_option);
DBUG_SET_INITIAL(argument);
opt_endinfo=1; /* unireg: memory allocation */
break;
#endif
case 'a':
global_system_variables.sql_mode= fix_sql_mode(MODE_ANSI);
global_system_variables.tx_isolation= ISO_SERIALIZABLE;
......
# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
# Copyright (C) 2000-2008 MySQL AB
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......
#
# This should contain a description of the file format for most Maria files
#
# Description of the header in the index file
Header, 24 bytes
Pos Length
0 4 file_version
4 2 options
6 2 header_length
8 2 state_info_length
10 2 base_info_length
12 2 base_pos
14 2 key_parts
16 2 unique_key_parts
18 1 keys
19 1 uniques
20 1 language
21 1 fulltext_keys
22 1 data_file_type
23 1 org_data_file_type
Status part
24 2 open_count
26 2 state_changed
28 7 create_rename_lsn
7 is_of_horizon
7 skip_redo_lsn
8 state.records
8 state->state.del
8 state->split
8 state->dellink
8 state->first_bitmap_with_space
8 state->state.key_file_length
8 state->state.data_file_length
8 state->state.empty
8 state->state.key_empty
8 state->auto_increment
8 state->state.checksum
4 state->process
4 state->unique
4 state->status
4 state->update_count
1 state->sortkey
1 reserved
for each key
8 state->key_root[i]
8 state->key_del
4 state->sec_index_changed
4 state->sec_index_used
4 state->version
8 state->key_map
8 state->create_time
8 state->recover_time
8 state->check_time
8 state->records_at_analyze
for each key
4 reserved
for each key part
8 state->rec_per_key_part[i]
4 state->nulls_per_key_part[i]
......@@ -1494,7 +1494,6 @@ int ha_maria::preload_keys(THD * thd, HA_CHECK_OPT *check_opt)
maria_extra(file, HA_EXTRA_PRELOAD_BUFFER_SIZE,
(void*) &thd->variables.preload_buff_size);
#ifdef NOT_YET
int error;
if ((error= maria_preload(file, map, table_list->ignore_leaves)))
......@@ -1525,7 +1524,6 @@ int ha_maria::preload_keys(THD * thd, HA_CHECK_OPT *check_opt)
_ma_check_print_error(&param, errmsg);
DBUG_RETURN(HA_ADMIN_FAILED);
}
#endif
DBUG_RETURN(HA_ADMIN_OK);
}
......@@ -2759,7 +2757,7 @@ static int ha_maria_init(void *p)
res= maria_init() || ma_control_file_create_or_open() ||
!init_pagecache(maria_pagecache,
(size_t) pagecache_buffer_size, pagecache_division_limit,
pagecache_age_threshold, MARIA_KEY_BLOCK_LENGTH, 0) ||
pagecache_age_threshold, maria_block_size, 0) ||
!init_pagecache(maria_log_pagecache,
TRANSLOG_PAGECACHE_SIZE, 0, 0,
TRANSLOG_PAGE_SIZE, 0) ||
......
......@@ -75,7 +75,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
DBUG_PRINT("enter", ("keys: %u columns: %u uniques: %u flags: %u",
keys, columns, uniques, flags));
DBUG_ASSERT(maria_block_size && maria_block_size % IO_SIZE == 0);
DBUG_ASSERT(maria_block_size && maria_block_size % MARIA_MIN_KEY_BLOCK_LENGTH == 0);
LINT_INIT(dfile);
LINT_INIT(file);
......
......@@ -488,10 +488,10 @@ int _ma_test_if_changed(register MARIA_HA *info)
/*
Put a mark in the .MYI file that someone is updating the table
Put a mark in the .MAI file that someone is updating the table
DOCUMENTATION
state.open_count in the .MYI file is used the following way:
state.open_count in the .MAI file is used the following way:
- For the first change of the .MYI file in this process open_count is
incremented by _ma_mark_file_changed(). (We have a write lock on the file
when this happens)
......@@ -505,7 +505,6 @@ int _ma_test_if_changed(register MARIA_HA *info)
open_count is not maintained on disk for transactional or temporary tables.
*/
int _ma_mark_file_changed(MARIA_HA *info)
{
uchar buff[3];
......@@ -541,7 +540,10 @@ int _ma_mark_file_changed(MARIA_HA *info)
!(share->state.changed & STATE_NOT_MOVABLE))
{
/* Lock table to current installation */
if (_ma_set_uuid(info, 0))
if (_ma_set_uuid(info, 0) ||
(share->state.create_rename_lsn == LSN_REPAIRED_BY_MARIA_CHK &&
_ma_update_state_lsns_sub(share, translog_get_horizon(),
TRUE, TRUE)))
DBUG_RETURN(1);
share->state.changed|= STATE_NOT_MOVABLE;
}
......
......@@ -396,8 +396,12 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
goto err;
}
/*
We can ignore testing uuid if STATE_NOT_MOVABLE is set, as in this
case the uuid will be set in _ma_mark_file_changed()
*/
if ((share->state.changed & STATE_NOT_MOVABLE) &&
share->now_transactional &&
share->base.born_transactional &&
!(open_flags & HA_OPEN_IGNORE_MOVED_STATE) &&
memcmp(share->base.uuid, maria_uuid, MY_UUID_SIZE))
{
......@@ -654,7 +658,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
import into the server. It starts its existence (from the point of
view of the server, including server's recovery) now.
*/
if ((open_flags & HA_OPEN_FROM_SQL_LAYER) || maria_in_recovery)
if (((open_flags & HA_OPEN_FROM_SQL_LAYER) &&
(share->state.changed & STATE_NOT_MOVABLE)) || maria_in_recovery)
_ma_update_state_lsns_sub(share, translog_get_horizon(),
TRUE, TRUE);
}
......
......@@ -2,8 +2,7 @@
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
......@@ -1331,6 +1330,7 @@ static void unlink_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block)
{
DBUG_ENTER("unlink_block");
DBUG_PRINT("unlink_block", ("unlink 0x%lx", (ulong)block));
DBUG_ASSERT(block->next_used != NULL);
if (block->next_used == block)
{
/* The list contains only one member */
......@@ -2216,7 +2216,7 @@ static void info_change_lock(PAGECACHE_BLOCK_LINK *block, my_bool wl)
@retval 1 Can't lock this block, need retry
*/
static my_bool translog_wait_lock(PAGECACHE *pagecache,
static my_bool pagecache_wait_lock(PAGECACHE *pagecache,
PAGECACHE_BLOCK_LINK *block,
PAGECACHE_FILE file,
pgcache_page_no_t pageno,
......@@ -2225,7 +2225,7 @@ static my_bool translog_wait_lock(PAGECACHE *pagecache,
/* Lock failed we will wait */
#ifdef THREAD
struct st_my_thread_var *thread= my_thread_var;
DBUG_ENTER("translog_wait_lock");
DBUG_ENTER("pagecache_wait_lock");
DBUG_PRINT("info", ("fail to lock, waiting... 0x%lx", (ulong)block));
thread->lock_type= lock_type;
wqueue_add_to_queue(&block->wqueue[COND_FOR_WRLOCK], thread);
......@@ -2301,7 +2301,7 @@ static my_bool get_wrlock(PAGECACHE *pagecache,
block->rlocks)
{
/* Lock failed we will wait */
if (translog_wait_lock(pagecache, block, file, pageno,
if (pagecache_wait_lock(pagecache, block, file, pageno,
MY_PTHREAD_LOCK_WRITE))
DBUG_RETURN(1);
}
......@@ -2344,7 +2344,7 @@ static my_bool get_rdlock(PAGECACHE *pagecache,
while (block->wlocks && !pthread_equal(block->write_locker, locker))
{
/* Lock failed we will wait */
if (translog_wait_lock(pagecache, block, file, pageno,
if (pagecache_wait_lock(pagecache, block, file, pageno,
MY_PTHREAD_LOCK_READ))
DBUG_RETURN(1);
}
......@@ -2439,20 +2439,17 @@ static void release_rdlock(PAGECACHE_BLOCK_LINK *block)
DBUG_VOID_RETURN;
}
/*
Try to lock/unlock and pin/unpin the block
/**
@brief Try to lock/unlock and pin/unpin the block
SYNOPSIS
make_lock_and_pin()
pagecache pointer to a page cache data structure
block the block to work with
lock lock change mode
pin pinchange mode
file File handler requesting pin
@param pagecache pointer to a page cache data structure
@param block the block to work with
@param lock lock change mode
@param pin pinchange mode
@param file File handler requesting pin
RETURN
0 - OK
1 - Try to lock the block failed
@retval 0 OK
@retval 1 Try to lock the block failed
*/
static my_bool make_lock_and_pin(PAGECACHE *pagecache,
......@@ -2550,8 +2547,6 @@ static my_bool make_lock_and_pin(PAGECACHE *pagecache,
PCBLOCK_INFO(block);
DBUG_ASSERT(block->hash_link->requests > 0);
block->hash_link->requests--;
DBUG_ASSERT(block->requests > 0);
unreg_request(pagecache, block, 1);
PCBLOCK_INFO(block);
DBUG_RETURN(1);
......@@ -3115,6 +3110,7 @@ uchar *pagecache_read(PAGECACHE *pagecache,
int error= 0;
enum pagecache_page_pin pin= lock_to_pin[test(buff==0)][lock];
PAGECACHE_BLOCK_LINK *fake_link;
my_bool reg_request;
#ifndef DBUG_OFF
char llbuf[22];
DBUG_ENTER("pagecache_read");
......@@ -3153,11 +3149,11 @@ uchar *pagecache_read(PAGECACHE *pagecache,
inc_counter_for_resize_op(pagecache);
pagecache->global_cache_r_requests++;
/* See NOTE for pagecache_unlock about registering requests. */
reg_request= ((pin == PAGECACHE_PIN_LEFT_UNPINNED) ||
(pin == PAGECACHE_PIN));
block= find_block(pagecache, file, pageno, level,
test(lock == PAGECACHE_LOCK_WRITE),
test((pin == PAGECACHE_PIN_LEFT_UNPINNED) ||
(pin == PAGECACHE_PIN)),
&page_st);
reg_request, &page_st);
DBUG_PRINT("info", ("Block type: %s current type %s",
page_cache_page_type_str[block->type],
page_cache_page_type_str[type]));
......@@ -3196,6 +3192,8 @@ uchar *pagecache_read(PAGECACHE *pagecache,
We failed to write lock the block, cache is unlocked,
we will try to get the block again.
*/
if (reg_request)
unreg_request(pagecache, block, 1);
pagecache_pthread_mutex_unlock(&pagecache->cache_lock);
DBUG_PRINT("info", ("restarting..."));
goto restart;
......@@ -3327,9 +3325,10 @@ static my_bool pagecache_delete_internal(PAGECACHE *pagecache,
*/
}
/* Cache is locked, so we can relese page before freeing it */
make_lock_and_pin(pagecache, block,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN);
if (make_lock_and_pin(pagecache, block,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN))
DBUG_ASSERT(0);
DBUG_ASSERT(block->hash_link->requests > 0);
page_link->requests--;
/* See NOTE for pagecache_unlock about registering requests. */
......@@ -3374,24 +3373,24 @@ my_bool pagecache_delete_by_link(PAGECACHE *pagecache,
lock == PAGECACHE_LOCK_LEFT_WRITELOCKED);
DBUG_ASSERT(block->pins != 0); /* should be pinned */
restart:
if (pagecache->can_be_used)
{
pagecache_pthread_mutex_lock(&pagecache->cache_lock);
if (!pagecache->can_be_used)
goto end;
/*
This block should be pinned (i.e. has not zero request counter) =>
Such block can't be chosen for eviction.
*/
DBUG_ASSERT((block->status &
(PCBLOCK_IN_SWITCH | PCBLOCK_REASSIGNED)) == 0);
/*
make_lock_and_pin() can't fail here, because we are keeping pin on the
block and it can't be evicted (which is cause of lock fail and retry)
*/
if (make_lock_and_pin(pagecache, block, lock, pin))
{
/*
We failed to writelock the block, cache is unlocked, and last write
lock is released, we will try to get the block again.
*/
pagecache_pthread_mutex_unlock(&pagecache->cache_lock);
DBUG_PRINT("info", ("restarting..."));
goto restart;
}
DBUG_ASSERT(0);
/*
get_present_hash_link() side effect emulation before call
......@@ -3494,6 +3493,16 @@ my_bool pagecache_delete(PAGECACHE *pagecache,
DBUG_RETURN(0);
}
block= page_link->block;
if (block->status & (PCBLOCK_REASSIGNED | PCBLOCK_IN_SWITCH))
{
DBUG_PRINT("info", ("Block 0x%0lx already is %s",
(ulong) block,
((block->status & PCBLOCK_REASSIGNED) ?
"reassigned" : "in switch")));
PCBLOCK_INFO(block);
page_link->requests--;
goto end;
}
/* See NOTE for pagecache_unlock about registering requests. */
if (pin == PAGECACHE_PIN)
reg_requests(pagecache, block, 1);
......@@ -3504,6 +3513,8 @@ my_bool pagecache_delete(PAGECACHE *pagecache,
We failed to writelock the block, cache is unlocked, and last write
lock is released, we will try to get the block again.
*/
if (pin == PAGECACHE_PIN)
unreg_request(pagecache, block, 1);
pagecache_pthread_mutex_unlock(&pagecache->cache_lock);
DBUG_PRINT("info", ("restarting..."));
goto restart;
......@@ -3639,6 +3650,7 @@ my_bool pagecache_write_part(PAGECACHE *pagecache,
PAGECACHE_BLOCK_LINK *fake_link;
int error= 0;
int need_lock_change= write_lock_change_table[lock].need_lock_change;
my_bool reg_request;
#ifndef DBUG_OFF
char llbuf[22];
DBUG_ENTER("pagecache_write_part");
......@@ -3683,14 +3695,14 @@ my_bool pagecache_write_part(PAGECACHE *pagecache,
inc_counter_for_resize_op(pagecache);
pagecache->global_cache_w_requests++;
/* See NOTE for pagecache_unlock about registering requests. */
reg_request= ((pin == PAGECACHE_PIN_LEFT_UNPINNED) ||
(pin == PAGECACHE_PIN));
block= find_block(pagecache, file, pageno, level,
test(write_mode != PAGECACHE_WRITE_DONE &&
lock != PAGECACHE_LOCK_LEFT_WRITELOCKED &&
lock != PAGECACHE_LOCK_WRITE_UNLOCK &&
lock != PAGECACHE_LOCK_WRITE_TO_READ),
test((pin == PAGECACHE_PIN_LEFT_UNPINNED) ||
(pin == PAGECACHE_PIN)),
&page_st);
reg_request, &page_st);
if (!block)
{
DBUG_ASSERT(write_mode != PAGECACHE_WRITE_DONE);
......@@ -3723,6 +3735,8 @@ my_bool pagecache_write_part(PAGECACHE *pagecache,
We failed to writelock the block, cache is unlocked, and last write
lock is released, we will try to get the block again.
*/
if (reg_request)
unreg_request(pagecache, block, 1);
pagecache_pthread_mutex_unlock(&pagecache->cache_lock);
DBUG_PRINT("info", ("restarting..."));
goto restart;
......@@ -4041,9 +4055,10 @@ static int flush_cached_blocks(PAGECACHE *pagecache,
pagecache->readwrite_flags);
pagecache_pthread_mutex_lock(&pagecache->cache_lock);
make_lock_and_pin(pagecache, block,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN);
if (make_lock_and_pin(pagecache, block,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN))
DBUG_ASSERT(0);
pagecache->global_cache_write++;
if (error)
......
......@@ -2,8 +2,7 @@
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
......
......@@ -2,8 +2,7 @@
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
......
/* TODO: copyright & Co */
/* Copyright (C) 2007-2008 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "maria_def.h"
......
......@@ -36,70 +36,81 @@
At present pages for all indexes are preloaded.
In future only pages for indexes specified in the key_map parameter
of the table will be preloaded.
We don't yet use preload_buff_size (we read page after page).
*/
int maria_preload(MARIA_HA *info, ulonglong key_map, my_bool ignore_leaves)
{
ulong length, block_length= 0;
ulong block_length= 0;
uchar *buff= NULL;
MARIA_SHARE* share= info->s;
uint keys= share->state.header.keys;
uint keynr;
my_off_t key_file_length= share->state.state.key_file_length;
my_off_t pos= share->base.keystart;
pgcache_page_no_t page_no, page_no_max;
PAGECACHE_BLOCK_LINK *page_link;
DBUG_ENTER("maria_preload");
if (!keys || !maria_is_any_key_active(key_map) || key_file_length == pos)
if (!share->state.header.keys || !maria_is_any_key_active(key_map) ||
(key_file_length == share->base.keystart))
DBUG_RETURN(0);
block_length= share->pagecache->block_size;
length= info->preload_buff_size/block_length * block_length;
set_if_bigger(length, block_length);
if (!(buff= (uchar *) my_malloc(length, MYF(MY_WME))))
if (!(buff= (uchar *) my_malloc(block_length, MYF(MY_WME))))
DBUG_RETURN(my_errno= HA_ERR_OUT_OF_MEM);
if (flush_pagecache_blocks(share->pagecache, &share->kfile, FLUSH_RELEASE))
goto err;
do
/*
Currently when we come here all other open instances of the table have
been closed, and we flushed all pages of our own instance, so there
cannot be any page of this table in the cache. Thus my_pread() would be
safe. But in the future, we will allow more concurrency during
preloading, so we use pagecache_read() instead of my_pread() because we
observed that on some Linux, concurrent pread() and pwrite() (which
could be from a page eviction by another thread) to the same page can
make pread() see an half-written page.
In this future, we should find a way to read state.key_file_length
reliably, handle concurrent shrinks (delete_all_rows()) etc.
*/
for ((page_no= share->base.keystart / block_length),
(page_no_max= key_file_length / block_length);
page_no < page_no_max; page_no++)
{
uchar *end;
/* Read the next block of index file into the preload buffer */
if ((my_off_t) length > (key_file_length-pos))
length= (ulong) (key_file_length-pos);
if (my_pread(share->kfile.file, (uchar*) buff, length, pos,
MYF(MY_FAE|MY_FNABP)))
/**
@todo instead of reading pages one by one we could have a call
pagecache_read_several_pages() which does a single my_pread() for many
consecutive pages (like the my_pread() in mi_preload()).
*/
if (pagecache_read(share->pagecache, &share->kfile, page_no,
DFLT_INIT_HITS, (uchar*) buff, share->page_type,
PAGECACHE_LOCK_WRITE, &page_link) == NULL)
goto err;
for (end= buff + length ; buff < end ; buff+= block_length)
keynr= _ma_get_keynr(share, buff);
if (((ignore_leaves && !_ma_test_if_nod(share, buff)) ||
keynr == MARIA_DELETE_KEY_NR ||
!(key_map & ((ulonglong) 1 << keynr))) &&
(pagecache_pagelevel(page_link) == DFLT_INIT_HITS))
{
uint keynr= _ma_get_keynr(share, buff);
if ((ignore_leaves && !_ma_test_if_nod(share, buff)) ||
keynr == MARIA_DELETE_KEY_NR ||
!(key_map & ((ulonglong) 1 << keynr)))
{
DBUG_ASSERT(share->pagecache->block_size == block_length);
if (pagecache_write(share->pagecache,
&share->kfile,
(pgcache_page_no_t) (pos / block_length),
DFLT_INIT_HITS,
(uchar*) buff,
PAGECACHE_PLAIN_PAGE,
PAGECACHE_LOCK_LEFT_UNLOCKED,
PAGECACHE_PIN_LEFT_UNPINNED,
PAGECACHE_WRITE_DONE, 0,
LSN_IMPOSSIBLE))
goto err;
}
pos+= block_length;
/*
This page is not interesting, and (last condition above) we are the
ones who put it in the cache, so nobody else is interested in it.
*/
if (pagecache_delete_by_link(share->pagecache, page_link,
PAGECACHE_LOCK_LEFT_WRITELOCKED, FALSE))
goto err;
}
else /* otherwise it stays in cache: */
pagecache_unlock_by_link(share->pagecache, page_link,
PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_UNPIN,
LSN_IMPOSSIBLE, LSN_IMPOSSIBLE, FALSE);
}
while (pos != key_file_length);
my_free((char*) buff, MYF(0));
my_free(buff, MYF(0));
DBUG_RETURN(0);
err:
my_free((char*) buff, MYF(MY_ALLOW_ZERO_PTR));
my_free(buff, MYF(MY_ALLOW_ZERO_PTR));
DBUG_RETURN(my_errno= errno);
}
......@@ -29,7 +29,7 @@
#include "ma_control_file.h"
/* For testing recovery */
#ifndef DBUG_OFF
#ifdef TO_BE_REMOVED
#define IDENTICAL_PAGES_AFTER_RECOVERY 1
#endif
/* Do extra sanity checking */
......
......@@ -93,3 +93,5 @@ SET_TARGET_PROPERTIES(ma_pagecache_consist_1kWR-t
ADD_EXECUTABLE(ma_pagecache_consist_64kWR-t ${ma_pagecache_consist_src})
SET_TARGET_PROPERTIES(ma_pagecache_consist_64kWR-t
PROPERTIES COMPILE_FLAGS "${ma_pagecache_common_cppflags} -DTEST_PAGE_SIZE=65536 -DTEST_WRITERS")
ADD_EXECUTABLE(ma_pagecache_rwconsist_1k-t ma_pagecache_rwconsist.c)
SET_TARGET_PROPERTIES(ma_pagecache_rwconsist_1k-t PROPERTIES COMPILE_FLAGS "-DTEST_PAGE_SIZE=1024")
# Copyright (C) 2006 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
# Copyright (C) 2006-2008 MySQL AB
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
......
......@@ -2,8 +2,7 @@
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
......
......@@ -2,8 +2,7 @@
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
......
......@@ -2,8 +2,7 @@
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
......
......@@ -2,8 +2,7 @@
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
......
/* TODO: copyright */
/* Copyright (C) 2006-2008 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "../maria_def.h"
......
/* Copyright (C) 2006-2008 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "../maria_def.h"
#include <my_dir.h>
......
/* Copyright (C) 2006-2008 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
TODO: use pthread_join instead of wait_for_thread_count_to_be_zero, like in
my_atomic-t.c (see BUG#22320).
......
/* Copyright (C) 2006-2008 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
TODO: use pthread_join instead of wait_for_thread_count_to_be_zero, like in
my_atomic-t.c (see BUG#22320).
......@@ -16,7 +31,7 @@ static const char* default_dbug_option;
#endif
#define SLEEP usleep(5)
#define SLEEP my_sleep(5)
static char *file1_name= (char*)"page_cache_test_file_1";
static PAGECACHE_FILE file1;
......
/* Copyright (C) 2006-2008 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
TODO: use pthread_join instead of wait_for_thread_count_to_be_zero, like in
my_atomic-t.c (see BUG#22320).
......
/* Copyright (C) 2006-2008 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "../maria_def.h"
#include <stdio.h>
#include <errno.h>
......
/* Copyright (C) 2006-2008 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "../maria_def.h"
#include <stdio.h>
#include <errno.h>
......
/* Copyright (C) 2006-2008 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "../maria_def.h"
#include <stdio.h>
#include <errno.h>
......
/* Copyright (C) 2006-2008 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "../maria_def.h"
#include <stdio.h>
#include <errno.h>
......
/* Copyright (C) 2006-2008 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "../maria_def.h"
#include <stdio.h>
#include <errno.h>
......
/* Copyright (C) 2006-2008 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "../maria_def.h"
#include <stdio.h>
#include <errno.h>
......
/* Copyright (C) 2006-2008 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "../maria_def.h"
#include <stdio.h>
#include <errno.h>
......
/* Copyright (C) 2006-2008 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "../maria_def.h"
#include <stdio.h>
#include <errno.h>
......
/* Copyright (C) 2006-2008 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "../maria_def.h"
#include <stdio.h>
#include <errno.h>
......
/* Copyright (C) 2006-2008 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <tap.h>
#include <my_sys.h>
#include <my_dir.h>
......
/* Copyright (C) 2006-2008 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <m_string.h>
#include "../ma_pagecache.h"
......
......@@ -2,8 +2,7 @@
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
......
......@@ -33,7 +33,7 @@
#ifdef HAVE_LONG_LONG
#define LONG ulonglong
#else
#define LONG ulonglong
#define LONG ulong
#endif
void bmove512(uchar *to, const uchar *from, register size_t length)
......
......@@ -29,26 +29,38 @@
char *strmake(register char *dst, register const char *src, size_t length)
{
#ifdef EXTRA_DEBUG
/*
'length' is the maximum length of the string; the buffer needs
to be one character larger to accomodate the terminating '\0'.
This is easy to get wrong, so we make sure we write to the
entire length of the buffer to identify incorrect buffer-sizes.
We only initialise the "unused" part of the buffer here, a) for
efficiency, and b) because dst==src is allowed, so initialising
the entire buffer would overwrite the source-string. Also, we
write a character rather than '\0' as this makes spotting these
problems in the results easier.
*/
uint n= strlen(src) + 1;
if (n <= length)
memset(dst + n, (int) 'Z', length - n + 1);
#endif
while (length--)
{
if (! (*dst++ = *src++))
{
#ifdef EXTRA_DEBUG
/*
'length' is the maximum length of the string; the buffer needs
to be one character larger to accommodate the terminating
'\0'. This is easy to get wrong, so we make sure we write to
the entire length of the buffer to identify incorrect
buffer-sizes. We only initialism the "unused" part of the
buffer here, a) for efficiency, and b) because dst==src is
allowed, so initializing the entire buffer would overwrite the
source-string. Also, we write a character rather than '\0' as
this makes spotting these problems in the results easier.
If we are using purify/valgrind, we only set one character at
end to be able to detect also wrong accesses after the end of
dst.
*/
if (length)
{
#ifdef HAVE_purify
dst[length-1]= 'Z';
#else
bfill(dst, length-1, (int) 'Z');
#endif /* HAVE_purify */
}
#endif /* EXTRA_DEBUG */
return dst-1;
}
}
*dst=0;
return dst;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment