| 3046 | |
| 3047 | |
| 3048 | my_bool |
| 3049 | Query_cache::append_result_data(Query_cache_block **current_block, |
| 3050 | size_t data_len, uchar* data, |
| 3051 | Query_cache_block *query_block) |
| 3052 | { |
| 3053 | DBUG_ENTER("Query_cache::append_result_data"); |
| 3054 | DBUG_PRINT("qcache", ("append %zu bytes to %p query", |
| 3055 | data_len, query_block)); |
| 3056 | |
| 3057 | if (query_block->query()->add(data_len) > query_cache_limit) |
| 3058 | { |
| 3059 | DBUG_PRINT("qcache", ("size limit reached %zu > %zu", |
| 3060 | query_block->query()->length(), |
| 3061 | query_cache_limit)); |
| 3062 | DBUG_RETURN(0); |
| 3063 | } |
| 3064 | if (*current_block == 0) |
| 3065 | { |
| 3066 | DBUG_PRINT("qcache", ("allocated first result data block %zu", data_len)); |
| 3067 | DBUG_RETURN(write_result_data(current_block, data_len, data, query_block, |
| 3068 | Query_cache_block::RES_BEG)); |
| 3069 | } |
| 3070 | Query_cache_block *last_block = (*current_block)->prev; |
| 3071 | |
| 3072 | DBUG_PRINT("qcache", ("lastblock %p len %zu used %zu", |
| 3073 | last_block, last_block->length, |
| 3074 | last_block->used)); |
| 3075 | my_bool success = 1; |
| 3076 | size_t last_block_free_space= last_block->length - last_block->used; |
| 3077 | |
| 3078 | /* |
| 3079 | We will first allocate and write the 'tail' of data, that doesn't fit |
| 3080 | in the 'last_block'. Only if this succeeds, we will fill the last_block. |
| 3081 | This saves us a memcpy if the query doesn't fit in the query cache. |
| 3082 | */ |
| 3083 | |
| 3084 | // Try join blocks if physically next block is free... |
| 3085 | size_t tail = data_len - last_block_free_space; |
| 3086 | size_t append_min = get_min_append_result_data_size(); |
| 3087 | if (last_block_free_space < data_len && |
| 3088 | append_next_free_block(last_block, |
| 3089 | MY_MAX(tail, append_min))) |
| 3090 | last_block_free_space = last_block->length - last_block->used; |
| 3091 | // If no space in last block (even after join) allocate new block |
| 3092 | if (last_block_free_space < data_len) |
| 3093 | { |
| 3094 | DBUG_PRINT("qcache", ("allocate new block for %zu bytes", |
| 3095 | data_len-last_block_free_space)); |
| 3096 | Query_cache_block *new_block = 0; |
| 3097 | success = write_result_data(&new_block, data_len-last_block_free_space, |
| 3098 | (uchar*)(((uchar*)data)+last_block_free_space), |
| 3099 | query_block, |
| 3100 | Query_cache_block::RES_CONT); |
| 3101 | /* |
| 3102 | new_block may be != 0 even !success (if write_result_data |
| 3103 | allocate a small block but failed to allocate continue) |
| 3104 | */ |
| 3105 | if (new_block != 0) |