| 4571 | |
| 4572 | |
| 4573 | my_bool Query_cache::join_results(size_t join_limit) |
| 4574 | { |
| 4575 | my_bool has_moving = 0; |
| 4576 | DBUG_ENTER("Query_cache::join_results"); |
| 4577 | |
| 4578 | if (queries_blocks != 0) |
| 4579 | { |
| 4580 | DBUG_ASSERT(query_cache_size > 0); |
| 4581 | Query_cache_block *block = queries_blocks; |
| 4582 | do |
| 4583 | { |
| 4584 | Query_cache_query *header = block->query(); |
| 4585 | if (header->result() != 0 && |
| 4586 | header->result()->type == Query_cache_block::RESULT && |
| 4587 | header->length() > join_limit) |
| 4588 | { |
| 4589 | Query_cache_block *new_result_block = |
| 4590 | get_free_block(ALIGN_SIZE(header->length()) + |
| 4591 | ALIGN_SIZE(sizeof(Query_cache_block)) + |
| 4592 | ALIGN_SIZE(sizeof(Query_cache_result)), 1, 0); |
| 4593 | if (new_result_block != 0) |
| 4594 | { |
| 4595 | has_moving = 1; |
| 4596 | Query_cache_block *first_result = header->result(); |
| 4597 | size_t new_len = (header->length() + |
| 4598 | ALIGN_SIZE(sizeof(Query_cache_block)) + |
| 4599 | ALIGN_SIZE(sizeof(Query_cache_result))); |
| 4600 | if (new_result_block->length > |
| 4601 | ALIGN_SIZE(new_len) + min_allocation_unit) |
| 4602 | split_block(new_result_block, ALIGN_SIZE(new_len)); |
| 4603 | BLOCK_LOCK_WR(block); |
| 4604 | header->result(new_result_block); |
| 4605 | new_result_block->type = Query_cache_block::RESULT; |
| 4606 | new_result_block->n_tables = 0; |
| 4607 | new_result_block->used = new_len; |
| 4608 | |
| 4609 | new_result_block->next = new_result_block->prev = new_result_block; |
| 4610 | DBUG_PRINT("qcache", ("new block %zu/%zu (%zu)", |
| 4611 | new_result_block->length, |
| 4612 | new_result_block->used, |
| 4613 | header->length())); |
| 4614 | |
| 4615 | Query_cache_result *new_result = new_result_block->result(); |
| 4616 | new_result->parent(block); |
| 4617 | uchar *write_to = (uchar*) new_result->data(); |
| 4618 | Query_cache_block *result_block = first_result; |
| 4619 | do |
| 4620 | { |
| 4621 | size_t len = (result_block->used - result_block->headers_len() - |
| 4622 | ALIGN_SIZE(sizeof(Query_cache_result))); |
| 4623 | DBUG_PRINT("loop", ("add block %zu/%zu (%zu)", |
| 4624 | result_block->length, |
| 4625 | result_block->used, |
| 4626 | len)); |
| 4627 | memcpy((char *) write_to, |
| 4628 | (char*) result_block->result()->data(), |
| 4629 | len); |
| 4630 | write_to += len; |