|
8 | 8 | * Portions Copyright (c) 1994, Regents of the University of California
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $Header: /cvsroot/pgsql/src/backend/storage/freespace/freespace.c,v 1.10 2001/11/05 17:46:27 momjian Exp $ |
| 11 | + * $Header: /cvsroot/pgsql/src/backend/storage/freespace/freespace.c,v 1.11 2002/01/24 15:31:43 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *
|
14 | 14 | * NOTES:
|
@@ -841,64 +841,59 @@ static bool
|
841 | 841 | insert_fsm_page_entry(FSMRelation *fsmrel, BlockNumber page, Size spaceAvail,
|
842 | 842 | FSMChunk *chunk, int chunkRelIndex)
|
843 | 843 | {
|
844 |
| - FSMChunk *newChunk; |
845 |
| - int newChunkRelIndex; |
846 |
| - |
847 |
| - if (fsmrel->numPages >= fsmrel->numChunks * CHUNKPAGES) |
| 844 | + /* Outer loop handles retry after compacting rel's page list */ |
| 845 | + for (;;) |
848 | 846 | {
|
849 |
| - /* No free space within chunk list, so need another chunk */ |
850 |
| - if ((newChunk = FreeSpaceMap->freeChunks) == NULL) |
851 |
| - return false; /* can't do it */ |
852 |
| - FreeSpaceMap->freeChunks = newChunk->next; |
853 |
| - FreeSpaceMap->numFreeChunks--; |
854 |
| - newChunk->next = NULL; |
855 |
| - newChunk->numPages = 0; |
856 |
| - if (fsmrel->relChunks == NULL) |
857 |
| - fsmrel->relChunks = newChunk; |
858 |
| - else |
| 847 | + if (fsmrel->numPages >= fsmrel->numChunks * CHUNKPAGES) |
859 | 848 | {
|
860 |
| - FSMChunk *priorChunk = fsmrel->relChunks; |
| 849 | + /* No free space within chunk list, so need another chunk */ |
| 850 | + FSMChunk *newChunk; |
| 851 | + |
| 852 | + if ((newChunk = FreeSpaceMap->freeChunks) == NULL) |
| 853 | + return false; /* can't do it */ |
| 854 | + FreeSpaceMap->freeChunks = newChunk->next; |
| 855 | + FreeSpaceMap->numFreeChunks--; |
| 856 | + newChunk->next = NULL; |
| 857 | + newChunk->numPages = 0; |
| 858 | + if (fsmrel->relChunks == NULL) |
| 859 | + fsmrel->relChunks = newChunk; |
| 860 | + else |
| 861 | + { |
| 862 | + FSMChunk *priorChunk = fsmrel->relChunks; |
861 | 863 |
|
862 |
| - while (priorChunk->next != NULL) |
863 |
| - priorChunk = priorChunk->next; |
864 |
| - priorChunk->next = newChunk; |
| 864 | + while (priorChunk->next != NULL) |
| 865 | + priorChunk = priorChunk->next; |
| 866 | + priorChunk->next = newChunk; |
| 867 | + } |
| 868 | + fsmrel->numChunks++; |
| 869 | + if (chunk == NULL) |
| 870 | + { |
| 871 | + /* Original search found that new page belongs at end */ |
| 872 | + chunk = newChunk; |
| 873 | + chunkRelIndex = 0; |
| 874 | + } |
865 | 875 | }
|
866 |
| - fsmrel->numChunks++; |
867 |
| - if (chunk == NULL) |
| 876 | + |
| 877 | + /* Try to insert it the easy way, ie, just move down subsequent data */ |
| 878 | + if (chunk && |
| 879 | + push_fsm_page_entry(page, spaceAvail, chunk, chunkRelIndex)) |
868 | 880 | {
|
869 |
| - /* Original search found that new page belongs at end */ |
870 |
| - chunk = newChunk; |
871 |
| - chunkRelIndex = 0; |
| 881 | + fsmrel->numPages++; |
| 882 | + fsmrel->nextPage++; /* don't return same page twice running */ |
| 883 | + return true; |
872 | 884 | }
|
873 |
| - } |
874 | 885 |
|
875 |
| - /* Try to insert it the easy way, ie, just move down subsequent data */ |
876 |
| - if (chunk && |
877 |
| - push_fsm_page_entry(page, spaceAvail, chunk, chunkRelIndex)) |
878 |
| - { |
879 |
| - fsmrel->numPages++; |
880 |
| - fsmrel->nextPage++; /* don't return same page twice running */ |
881 |
| - return true; |
882 |
| - } |
883 |
| - |
884 |
| - /* |
885 |
| - * There is space available, but evidently it's before the place where |
886 |
| - * the page entry needs to go. Compact the list and try again. This |
887 |
| - * will require us to redo the search for the appropriate place. |
888 |
| - */ |
889 |
| - compact_fsm_page_list(fsmrel); |
890 |
| - if (lookup_fsm_page_entry(fsmrel, page, &newChunk, &newChunkRelIndex)) |
891 |
| - elog(ERROR, "insert_fsm_page_entry: entry already exists!"); |
892 |
| - if (newChunk && |
893 |
| - push_fsm_page_entry(page, spaceAvail, newChunk, newChunkRelIndex)) |
894 |
| - { |
895 |
| - fsmrel->numPages++; |
896 |
| - fsmrel->nextPage++; /* don't return same page twice running */ |
897 |
| - return true; |
| 886 | + /* |
| 887 | + * There is space available, but evidently it's before the place where |
| 888 | + * the page entry needs to go. Compact the list and try again. This |
| 889 | + * will require us to redo the search for the appropriate place. |
| 890 | + * Furthermore, compact_fsm_page_list deletes empty end chunks, so |
| 891 | + * we may need to repeat the action of grabbing a new end chunk. |
| 892 | + */ |
| 893 | + compact_fsm_page_list(fsmrel); |
| 894 | + if (lookup_fsm_page_entry(fsmrel, page, &chunk, &chunkRelIndex)) |
| 895 | + elog(ERROR, "insert_fsm_page_entry: entry already exists!"); |
898 | 896 | }
|
899 |
| - /* Shouldn't get here given the initial if-test for space available */ |
900 |
| - elog(ERROR, "insert_fsm_page_entry: failed to insert entry!"); |
901 |
| - return false; /* keep compiler quiet */ |
902 | 897 | }
|
903 | 898 |
|
904 | 899 | /*
|
|
0 commit comments