summaryrefslogtreecommitdiff
path: root/mysys
diff options
context:
space:
mode:
Diffstat (limited to 'mysys')
-rw-r--r--mysys/mf_keycache.c89
1 files changed, 86 insertions, 3 deletions
diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c
index 45cbcdb3ab7..3276044fc2f 100644
--- a/mysys/mf_keycache.c
+++ b/mysys/mf_keycache.c
@@ -826,7 +826,7 @@ restart:
(uint) hash_link->file,(ulong) hash_link->diskpos));
}
}
- KEYCACHE_DBUG_ASSERT(n <= my_hash_links_used);
+ KEYCACHE_DBUG_ASSERT(cnt <= my_hash_links_used);
#endif
}
if (! hash_link)
@@ -1063,6 +1063,9 @@ restart:
KEYCACHE_DBUG_ASSERT(page_status != -1);
*page_st=page_status;
+ KEYCACHE_DBUG_PRINT("find_key_block",
+ ("file %u, filepos %lu, page_status %lu",
+ (uint) file,(ulong) filepos,(uint) page_status));
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
DBUG_EXECUTE("check_keycache2",test_key_cache("end of find_key_block",0););
@@ -1181,7 +1184,7 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
keycache_pthread_mutex_lock(&THR_LOCK_keycache);
my_cache_r_requests++;
block=find_key_block(file,filepos,0,&page_st);
- if (page_st != PAGE_READ)
+ if (block->status != BLOCK_ERROR && page_st != PAGE_READ)
{
/* The requested page is to be read into the block buffer */
read_block(block,key_cache_block_size,read_length+offset,
@@ -1256,6 +1259,86 @@ byte *key_cache_read(File file, my_off_t filepos, byte *buff, uint length,
/*
+ Insert a block of file data from a buffer into key cache
+
+ SYNOPSIS
+ key_cache_insert()
+ file file descriptor
+ filepos file offset of the data from the buffer
+ buff buffer with data to insert into key cache
+ length length of the data in the buffer
+
+ RETURN VALUE
+ 0 if a success, 1 -otherwise.
+*/
+
+int key_cache_insert(File file, my_off_t filepos, byte *buff, uint length)
+{
+ DBUG_ENTER("key_cache_insert");
+ DBUG_PRINT("enter", ("file %u, filepos %lu, length %u",
+ (uint) file,(ulong) filepos, length));
+
+ if (my_disk_blocks > 0)
+ {
+ /* Key cache is used */
+ reg1 BLOCK_LINK *block;
+ uint offset= (uint) (filepos & (key_cache_block_size-1));
+ uint read_length;
+ int page_st;
+
+ /* Read data into key cache from buff in key_cache_block_size increments */
+ filepos-= offset;
+ do
+ {
+ read_length= length > key_cache_block_size ?
+ key_cache_block_size : length;
+ KEYCACHE_DBUG_ASSERT(read_length > 0);
+ keycache_pthread_mutex_lock(&THR_LOCK_keycache);
+ my_cache_r_requests++;
+ block=find_key_block(file, filepos, 0, &page_st);
+ if (block->status != BLOCK_ERROR && page_st != PAGE_READ)
+ {
+ /* The requested page is to be read into the block buffer */
+#if !defined(SERIALIZED_READ_FROM_CACHE)
+ keycache_pthread_mutex_unlock(&THR_LOCK_keycache);
+#endif
+
+ /* Copy data from buff */
+ if (!(read_length & 511))
+ bmove512(block->buffer+offset, buff, read_length);
+ else
+ memcpy(block->buffer+offset, buff, (size_t) read_length);
+
+#if !defined(SERIALIZED_READ_FROM_CACHE)
+ keycache_pthread_mutex_lock(&THR_LOCK_keycache);
+#endif
+ block->status= BLOCK_READ;
+ block->length= read_length+offset;
+ }
+
+ remove_reader(block);
+ /*
+ Link the block into the LRU chain
+ if it's the last submitted request for the block
+ */
+ unreg_request(block,1);
+
+ keycache_pthread_mutex_unlock(&THR_LOCK_keycache);
+
+ if (block->status & BLOCK_ERROR)
+ DBUG_RETURN(1);
+
+ buff+=read_length;
+ filepos+=read_length;
+ offset=0;
+
+ } while ((length-= read_length));
+ }
+ DBUG_RETURN(0);
+}
+
+
+/*
Write a buffer into disk;
filepos must be a multiple of 'block_length', but it doesn't
have to be a multiple of key cache block size;
@@ -1303,7 +1386,7 @@ int key_cache_write(File file, my_off_t filepos, byte *buff, uint length,
keycache_pthread_mutex_lock(&THR_LOCK_keycache);
my_cache_w_requests++;
block=find_key_block(file, filepos, 1, &page_st);
- if (page_st != PAGE_READ &&
+ if (block->status != BLOCK_ERROR && page_st != PAGE_READ &&
(offset || read_length < key_cache_block_size))
read_block(block,
offset + read_length >= key_cache_block_size?