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{

87 int logpageno;

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)