Write array of pages to disk in efficient order. First, sort pages by their numbers to make writes physically ordered and thus faster. At every iteration of while loop write pages which have no high precedence pages to ensure order preserved. If after some iteration there are no such pages (i.e. all of not written yet pages have high precedence pages) then write them all at last iteration (of cour
| 2791 | // then write them all at last iteration (of course write_buffer will also check |
| 2792 | // for precedence before write). |
| 2793 | static void flushPages(thread_db* tdbb, USHORT flush_flag, BufferDesc** begin, FB_SIZE_T count) |
| 2794 | { |
| 2795 | FbStatusVector* const status = tdbb->tdbb_status_vector; |
| 2796 | const bool all_flag = (flush_flag & FLUSH_ALL) != 0; |
| 2797 | const bool release_flag = (flush_flag & FLUSH_RLSE) != 0; |
| 2798 | const bool write_thru = release_flag; |
| 2799 | |
| 2800 | qsort(begin, count, sizeof(BufferDesc*), cmpBdbs); |
| 2801 | |
| 2802 | MarkIterator<BufferDesc*> iter(begin, count); |
| 2803 | |
| 2804 | FB_SIZE_T written = 0; |
| 2805 | bool writeAll = false; |
| 2806 | |
| 2807 | while (!iter.isEmpty()) |
| 2808 | { |
| 2809 | bool found = false; |
| 2810 | for (; !iter.isEof(); ++iter) |
| 2811 | { |
| 2812 | BufferDesc* bdb = *iter; |
| 2813 | fb_assert(bdb); |
| 2814 | if (!bdb) |
| 2815 | continue; |
| 2816 | |
| 2817 | bdb->addRef(tdbb, release_flag ? SYNC_EXCLUSIVE : SYNC_SHARED); |
| 2818 | |
| 2819 | BufferControl* bcb = bdb->bdb_bcb; |
| 2820 | if (!writeAll) |
| 2821 | purgePrecedence(bcb, bdb); |
| 2822 | |
| 2823 | if (writeAll || QUE_EMPTY(bdb->bdb_higher)) |
| 2824 | { |
| 2825 | if (release_flag) |
| 2826 | { |
| 2827 | if (bdb->bdb_use_count > 1) |
| 2828 | BUGCHECK(210); // msg 210 page in use during flush |
| 2829 | } |
| 2830 | |
| 2831 | if (!all_flag || bdb->bdb_flags & (BDB_db_dirty | BDB_dirty)) |
| 2832 | { |
| 2833 | if (!write_buffer(tdbb, bdb, bdb->bdb_page, write_thru, status, true)) |
| 2834 | CCH_unwind(tdbb, true); |
| 2835 | } |
| 2836 | |
| 2837 | // release lock before losing control over bdb, it prevents |
| 2838 | // concurrent operations on released lock |
| 2839 | if (release_flag) |
| 2840 | PAGE_LOCK_RELEASE(tdbb, bcb, bdb->bdb_lock); |
| 2841 | |
| 2842 | bdb->release(tdbb, !release_flag && !(bdb->bdb_flags & BDB_dirty)); |
| 2843 | |
| 2844 | iter.mark(); |
| 2845 | found = true; |
| 2846 | written++; |
| 2847 | } |
| 2848 | else |
| 2849 | { |
| 2850 | bdb->release(tdbb, false); |
no test coverage detected