|
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,BlockNumberpage,SizespaceAvail,
|
842 | 842 | FSMChunk*chunk,intchunkRelIndex)
|
843 | 843 | {
|
844 |
| -FSMChunk*newChunk; |
845 |
| -intnewChunkRelIndex; |
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 | /*
|
|