| 2730 | */ |
| 2731 | |
| 2732 | int key_cache_insert(KEY_CACHE *keycache, |
| 2733 | File file, my_off_t filepos, int level, |
| 2734 | uchar *buff, uint length) |
| 2735 | { |
| 2736 | int error= 0; |
| 2737 | DBUG_ENTER("key_cache_insert"); |
| 2738 | DBUG_PRINT("enter", ("fd: %u pos: %lu length: %u", |
| 2739 | (uint) file,(ulong) filepos, length)); |
| 2740 | |
| 2741 | if (keycache->key_cache_inited) |
| 2742 | { |
| 2743 | /* Key cache is used */ |
| 2744 | reg1 BLOCK_LINK *block; |
| 2745 | uint read_length; |
| 2746 | uint offset; |
| 2747 | int page_st; |
| 2748 | my_bool locked_and_incremented= FALSE; |
| 2749 | |
| 2750 | /* |
| 2751 | When the keycache is once initialized, we use the cache_lock to |
| 2752 | reliably distinguish the cases of normal operation, resizing, and |
| 2753 | disabled cache. We always increment and decrement |
| 2754 | 'cnt_for_resize_op' so that a resizer can wait for pending I/O. |
| 2755 | */ |
| 2756 | keycache_pthread_mutex_lock(&keycache->cache_lock); |
| 2757 | /* |
| 2758 | We do not load index data into a disabled cache nor into an |
| 2759 | ongoing resize. |
| 2760 | */ |
| 2761 | if (!keycache->can_be_used || keycache->in_resize) |
| 2762 | goto no_key_cache; |
| 2763 | /* Register the pseudo I/O for the next resize. */ |
| 2764 | inc_counter_for_resize_op(keycache); |
| 2765 | locked_and_incremented= TRUE; |
| 2766 | /* Loaded data may not always be aligned to cache blocks. */ |
| 2767 | offset= (uint) (filepos % keycache->key_cache_block_size); |
| 2768 | /* Load data in key_cache_block_size increments. */ |
| 2769 | do |
| 2770 | { |
| 2771 | /* Cache could be disabled or resizing in a later iteration. */ |
| 2772 | if (!keycache->can_be_used || keycache->in_resize) |
| 2773 | goto no_key_cache; |
| 2774 | /* Start loading at the beginning of the cache block. */ |
| 2775 | filepos-= offset; |
| 2776 | /* Do not load beyond the end of the cache block. */ |
| 2777 | read_length= length; |
| 2778 | set_if_smaller(read_length, keycache->key_cache_block_size-offset); |
| 2779 | KEYCACHE_DBUG_ASSERT(read_length > 0); |
| 2780 | |
| 2781 | /* The block has been read by the caller already. */ |
| 2782 | keycache->global_cache_read++; |
| 2783 | /* Request the cache block that matches file/pos. */ |
| 2784 | keycache->global_cache_r_requests++; |
| 2785 | block= find_key_block(keycache, file, filepos, level, 0, &page_st); |
| 2786 | if (!block) |
| 2787 | { |
| 2788 | /* |
| 2789 | This happens only for requests submitted during key cache |
nothing calls this directly
no test coverage detected