PostgreSQL Source Code: src/backend/storage/freespace/freespace.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
25
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64#define FSM_CATEGORIES 256
65#define FSM_CAT_STEP (BLCKSZ / FSM_CATEGORIES)
66#define MaxFSMRequestSize MaxHeapTupleSize
67
68
69
70
71
72
73
74
75#define FSM_TREE_DEPTH ((SlotsPerFSMPage >= 1626) ? 3 : 4)
76
77#define FSM_ROOT_LEVEL (FSM_TREE_DEPTH - 1)
78#define FSM_BOTTOM_LEVEL 0
79
80
81
82
83
84typedef struct
85{
89
90
92
93
99
102
103
107
108
114 bool *eof_p);
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
138{
140
142}
143
144
145
146
147
148
149
150
151
152
155 Size oldSpaceAvail, Size spaceNeeded)
156{
161 int search_slot;
162
163
165
166 search_slot = fsm_set_and_search(rel, addr, slot, old_cat, search_cat);
167
168
169
170
171
172 if (search_slot != -1)
173 {
175
176
177
178
179
181 return blknum;
182 }
184}
185
186
187
188
189
190
191
192
193void
195{
199
200
202
204}
205
206
207
208
209
210void
212 Size spaceAvail)
213{
220
221
224
225
229
233
237}
238
239
240
241
242
245{
250
251
253
256 return 0;
259
261}
262
263
264
265
266
267
268
269
270
271
272
273
276{
279 uint16 first_removed_slot;
281
282
283
284
285
288
289
290 first_removed_address = fsm_get_location(nblocks, &first_removed_slot);
291
292
293
294
295
296
297
298 if (first_removed_slot > 0)
299 {
300 buf = fsm_readbuf(rel, first_removed_address, false);
303
305
306
308
310
311
312
313
314
315
316
317
319
320
321
322
323
324
325
326
327
328
329
330
333
335
337
339 }
340 else
341 {
345
346 }
347
348 return new_nfsmblocks;
349}
350
351
352
353
354
355
356
357void
359{
360 bool dummy;
361
362
365 &dummy);
366}
367
368
369
370
371
372
373
374
375
376void
378{
379 bool dummy;
380
381
384}
385
386
387
388
389
390
393{
394 int cat;
395
396 Assert(avail < BLCKSZ);
397
399 return 255;
400
402
403
404
405
406
407 if (cat > 254)
408 cat = 254;
409
410 return (uint8) cat;
411}
412
413
414
415
416
419{
420
421 if (cat == 255)
423 else
425}
426
427
428
429
430
433{
434 int cat;
435
436
438 elog(ERROR, "invalid FSM request size %zu", needed);
439
440 if (needed == 0)
441 return 1;
442
444
445 if (cat > 255)
446 cat = 255;
447
448 return (uint8) cat;
449}
450
451
452
453
456{
458 int leafno;
459 int l;
460
461
462
463
464
466 for (l = 0; l < addr.level; l++)
468
469
470 pages = 0;
472 {
473 pages += leafno + 1;
475 }
476
477
478
479
480
481 pages -= addr.level;
482
483
484 return pages - 1;
485}
486
487
488
489
492{
494
498
499 return addr;
500}
501
502
503
504
507{
510}
511
512
513
514
515
518{
520
522
526
527 return parent;
528}
529
530
531
532
533
536{
538
540
543
544 return child;
545}
546
547
548
549
550
551
552
555{
559
560
561
562
563
564
565
568 {
569
573 else
575 }
576
577
578
579
580
581
582
583
584
585
586
587
589 {
590 if (extend)
592 else
594 }
595 else
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
614 {
619 }
620 return buf;
621}
622
623
624
625
626
627
630{
634 fsm_nblocks,
636}
637
638
639
640
641
642
643
644
645static int
648{
651 int newslot = -1;
652
655
657
660
661 if (minValue != 0)
662 {
663
666 true);
667 }
668
670
671 return newslot;
672}
673
674
675
676
679{
680 int restarts = 0;
682
683 for (;;)
684 {
685 int slot;
687 uint8 max_avail = 0;
688
689
691
692
694 {
698 false);
699 if (slot == -1)
700 {
703 }
704 else
705 {
706
708 }
709 }
710 else
711 slot = -1;
712
713 if (slot != -1)
714 {
715
716
717
718
720 {
723
725 {
727 return blkno;
728 }
729
730
731
732
733
734
735
736
737
743 if (restarts++ > 10000)
746 }
747 else
748 {
750 }
752 }
754 {
755
756
757
758
760 }
761 else
762 {
765
766
767
768
769
770
771
772
773
774
775
776
777
780
781
782
783
784
785
786
787
788 if (restarts++ > 10000)
790
791
793 }
794 }
795}
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
814 bool *eof_p)
815{
819
820
823 {
824 *eof_p = true;
825 return 0;
826 }
827 else
828 *eof_p = false;
829
831
832
833
834
835
837 {
839 fsm_end;
840 uint16 fsm_start_slot,
841 fsm_end_slot;
842 int slot,
843 start_slot,
844 end_slot;
845 bool eof = false;
846
847
848
849
850
851
852
853
856
858 {
859 fsm_start = fsm_get_parent(fsm_start, &fsm_start_slot);
861 }
863
865 start_slot = fsm_start_slot;
867 start_slot = SlotsPerFSMPage;
868 else
869 start_slot = 0;
870
872 end_slot = fsm_end_slot;
875 else
876 end_slot = -1;
877
878 for (slot = start_slot; slot <= end_slot; slot++)
879 {
880 int child_avail;
881
883
884
885 if (!eof)
888 &eof);
889 else
890 child_avail = 0;
891
892
894 {
899 }
900 }
901 }
902
903
905
906
907
908
909
910
911
913
915
916 return max_avail;
917}
918
919
920
921
922
923
924
925static bool
927{
929
930
931
932
933
934
935
936
938 blknumber < smgr->smgr_cached_nblocks[MAIN_FORKNUM]) ||
940}
#define InvalidBlockNumber
static bool BlockNumberIsValid(BlockNumber blockNumber)
Buffer ExtendBufferedRelTo(BufferManagerRelation bmr, ForkNumber fork, BufferAccessStrategy strategy, uint32 flags, BlockNumber extend_to, ReadBufferMode mode)
void ReleaseBuffer(Buffer buffer)
void UnlockReleaseBuffer(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
void LockBuffer(Buffer buffer, int mode)
void MarkBufferDirtyHint(Buffer buffer, bool buffer_std)
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
#define BUFFER_LOCK_UNLOCK
#define BUFFER_LOCK_SHARE
#define RelationGetNumberOfBlocks(reln)
static Page BufferGetPage(Buffer buffer)
@ EB_CREATE_FORK_IF_NEEDED
#define BUFFER_LOCK_EXCLUSIVE
static bool BufferIsValid(Buffer bufnum)
void PageInit(Page page, Size pageSize, Size specialSize)
static bool PageIsNew(const PageData *page)
static char * PageGetContents(Page page)
#define MaxFSMRequestSize
static uint8 fsm_vacuum_page(Relation rel, FSMAddress addr, BlockNumber start, BlockNumber end, bool *eof_p)
static FSMAddress fsm_get_child(FSMAddress parent, uint16 slot)
static const FSMAddress FSM_ROOT_ADDRESS
void FreeSpaceMapVacuumRange(Relation rel, BlockNumber start, BlockNumber end)
static bool fsm_does_block_exist(Relation rel, BlockNumber blknumber)
static uint8 fsm_space_needed_to_cat(Size needed)
static uint8 fsm_space_avail_to_cat(Size avail)
static Size fsm_space_cat_to_avail(uint8 cat)
static BlockNumber fsm_logical_to_physical(FSMAddress addr)
static FSMAddress fsm_get_parent(FSMAddress child, uint16 *slot)
BlockNumber RecordAndGetPageWithFreeSpace(Relation rel, BlockNumber oldPage, Size oldSpaceAvail, Size spaceNeeded)
static FSMAddress fsm_get_location(BlockNumber heapblk, uint16 *slot)
static Buffer fsm_extend(Relation rel, BlockNumber fsm_nblocks)
static Buffer fsm_readbuf(Relation rel, FSMAddress addr, bool extend)
void FreeSpaceMapVacuum(Relation rel)
Size GetRecordedFreeSpace(Relation rel, BlockNumber heapBlk)
static int fsm_set_and_search(Relation rel, FSMAddress addr, uint16 slot, uint8 newValue, uint8 minValue)
void RecordPageWithFreeSpace(Relation rel, BlockNumber heapBlk, Size spaceAvail)
static BlockNumber fsm_search(Relation rel, uint8 min_cat)
void XLogRecordPageWithFreeSpace(RelFileLocator rlocator, BlockNumber heapBlk, Size spaceAvail)
BlockNumber GetPageWithFreeSpace(Relation rel, Size spaceNeeded)
static BlockNumber fsm_get_heap_blk(FSMAddress addr, uint16 slot)
BlockNumber FreeSpaceMapPrepareTruncateRel(Relation rel, BlockNumber nblocks)
uint8 fsm_get_avail(Page page, int slot)
uint8 fsm_get_max_avail(Page page)
bool fsm_set_avail(Page page, int slot, uint8 value)
bool fsm_truncate_avail(Page page, int nslots)
int fsm_search_avail(Buffer buf, uint8 minvalue, bool advancenext, bool exclusive_lock_held)
Assert(PointerIsAligned(start, uint64))
#define START_CRIT_SECTION()
#define CHECK_FOR_INTERRUPTS()
#define END_CRIT_SECTION()
static SMgrRelation RelationGetSmgr(Relation rel)
#define RelationNeedsWAL(relation)
BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum)
bool smgrexists(SMgrRelation reln, ForkNumber forknum)
BlockNumber smgr_cached_nblocks[MAX_FORKNUM+1]
#define XLogHintBitIsNeeded()
XLogRecPtr log_newpage_buffer(Buffer buffer, bool page_std)
Buffer XLogReadBufferExtended(RelFileLocator rlocator, ForkNumber forknum, BlockNumber blkno, ReadBufferMode mode, Buffer recent_buffer)