| 1446 | |
| 1447 | |
| 1448 | ULONG Sort::allocate(ULONG n, ULONG chunkSize, bool useFreeSpace) |
| 1449 | { |
| 1450 | /************************************** |
| 1451 | * |
| 1452 | * Allocate memory for first n runs |
| 1453 | * |
| 1454 | **************************************/ |
| 1455 | const ULONG rec_size = m_longs << SHIFTLONG; |
| 1456 | ULONG allocated = 0, count; |
| 1457 | run_control* run; |
| 1458 | |
| 1459 | // if some run's already in memory cache - use this memory |
| 1460 | for (run = m_runs, count = 0; count < n; run = run->run_next, count++) |
| 1461 | { |
| 1462 | run->run_buffer = NULL; |
| 1463 | |
| 1464 | UCHAR* const mem = m_space->inMemory(run->run_seek, run->run_size); |
| 1465 | |
| 1466 | if (mem) |
| 1467 | { |
| 1468 | run->run_buffer = mem; |
| 1469 | run->run_record = reinterpret_cast<sort_record*>(mem); |
| 1470 | run->run_end_buffer = run->run_buffer + run->run_size; |
| 1471 | run->run_seek += run->run_size; // emulate read |
| 1472 | allocated++; |
| 1473 | } |
| 1474 | |
| 1475 | run->run_buff_cache = (mem != NULL); |
| 1476 | } |
| 1477 | |
| 1478 | if (allocated == n || !useFreeSpace) |
| 1479 | return allocated; |
| 1480 | |
| 1481 | // try to use free blocks from memory cache of work file |
| 1482 | |
| 1483 | fb_assert(n > allocated); |
| 1484 | TempSpace::Segments segments(m_owner->getPool(), n - allocated); |
| 1485 | allocated += m_space->allocateBatch(n - allocated, m_max_alloc_size, chunkSize, segments); |
| 1486 | |
| 1487 | if (segments.getCount()) |
| 1488 | { |
| 1489 | TempSpace::SegmentInMemory *seg = segments.begin(), *lastSeg = segments.end(); |
| 1490 | for (run = m_runs, count = 0; count < n; run = run->run_next, count++) |
| 1491 | { |
| 1492 | if (!run->run_buffer) |
| 1493 | { |
| 1494 | const size_t runSize = MIN(seg->size / rec_size, run->run_records) * rec_size; |
| 1495 | UCHAR* mem = seg->memory; |
| 1496 | |
| 1497 | run->run_mem_seek = seg->position; |
| 1498 | run->run_mem_size = (ULONG) seg->size; |
| 1499 | run->run_buffer = mem; |
| 1500 | mem += runSize; |
| 1501 | run->run_record = reinterpret_cast<sort_record*>(mem); |
| 1502 | run->run_end_buffer = mem; |
| 1503 | |
| 1504 | seg++; |
| 1505 | if (seg == lastSeg) |
nothing calls this directly
no test coverage detected