| 2414 | } |
| 2415 | |
| 2416 | bool PageSpace::extend(thread_db* tdbb, const ULONG pageNum, const bool forceSize) |
| 2417 | { |
| 2418 | /************************************** |
| 2419 | * |
| 2420 | * Functional description |
| 2421 | * Extend database file(s) up to at least pageNum pages. Number of pages to |
| 2422 | * extend can't be less than hardcoded value MIN_EXTEND_BYTES and more than |
| 2423 | * configured value "DatabaseGrowthIncrement" (both values in bytes). |
| 2424 | * |
| 2425 | * If "DatabaseGrowthIncrement" is less than MIN_EXTEND_BYTES then don't |
| 2426 | * extend file(s) |
| 2427 | * |
| 2428 | * If forceSize is true, extend file up to pageNum pages (despite of value |
| 2429 | * of "DatabaseGrowthIncrement") and don't make attempts to extend by less |
| 2430 | * pages. |
| 2431 | * |
| 2432 | **************************************/ |
| 2433 | fb_assert(dbb == tdbb->getDatabase()); |
| 2434 | |
| 2435 | const int MAX_EXTEND_BYTES = dbb->dbb_config->getDatabaseGrowthIncrement(); |
| 2436 | |
| 2437 | if (pageNum < maxPageNumber || MAX_EXTEND_BYTES < MIN_EXTEND_BYTES && !forceSize) |
| 2438 | return true; |
| 2439 | |
| 2440 | if (pageNum >= maxAlloc()) |
| 2441 | { |
| 2442 | const ULONG minExtendPages = MIN_EXTEND_BYTES / dbb->dbb_page_size; |
| 2443 | const ULONG maxExtendPages = MAX_EXTEND_BYTES / dbb->dbb_page_size; |
| 2444 | const ULONG reqPages = pageNum - maxPageNumber + 1; |
| 2445 | |
| 2446 | ULONG extPages; |
| 2447 | extPages = MIN(MAX(maxPageNumber / 16, minExtendPages), maxExtendPages); |
| 2448 | extPages = MAX(reqPages, extPages); |
| 2449 | |
| 2450 | while (true) |
| 2451 | { |
| 2452 | const ULONG oldMaxPageNumber = maxPageNumber; |
| 2453 | try |
| 2454 | { |
| 2455 | PIO_extend(tdbb, file, extPages, dbb->dbb_page_size); |
| 2456 | break; |
| 2457 | } |
| 2458 | catch (const status_exception&) |
| 2459 | { |
| 2460 | if (extPages > reqPages && !forceSize) |
| 2461 | { |
| 2462 | fb_utils::init_status(tdbb->tdbb_status_vector); |
| 2463 | |
| 2464 | // if file was extended, return, else try to extend by less pages |
| 2465 | |
| 2466 | if (oldMaxPageNumber < maxAlloc()) |
| 2467 | return true; |
| 2468 | |
| 2469 | extPages = MAX(reqPages, extPages / 2); |
| 2470 | } |
| 2471 | else |
| 2472 | { |
| 2473 | gds__log("Error extending file \"%s\" by %lu page(s).\nCurrently allocated %lu pages, requested page number %lu", |
no test coverage detected