mmap opens the underlying memory-mapped file and initializes the meta references. minsz is the minimum size that the new mmap can be.
(minsz int)
| 454 | // mmap opens the underlying memory-mapped file and initializes the meta references. |
| 455 | // minsz is the minimum size that the new mmap can be. |
| 456 | func (db *DB) mmap(minsz int) (err error) { |
| 457 | db.mmaplock.Lock() |
| 458 | defer db.mmaplock.Unlock() |
| 459 | |
| 460 | lg := db.Logger() |
| 461 | |
| 462 | // Ensure the size is at least the minimum size. |
| 463 | var fileSize int |
| 464 | fileSize, err = db.fileSize() |
| 465 | if err != nil { |
| 466 | lg.Errorf("getting file size failed: %w", err) |
| 467 | return err |
| 468 | } |
| 469 | var size = fileSize |
| 470 | if size < minsz { |
| 471 | size = minsz |
| 472 | } |
| 473 | size, err = db.mmapSize(size) |
| 474 | if err != nil { |
| 475 | lg.Errorf("getting map size failed: %w", err) |
| 476 | return err |
| 477 | } |
| 478 | |
| 479 | if db.MaxSize > 0 && size > db.MaxSize { |
| 480 | // On Windows, the data file is expanded to the full mapped size during mmap, |
| 481 | // so we must reject any mmap size larger than the configured max size. |
| 482 | // |
| 483 | // On other platforms, mmap itself does not grow the file immediately, so the |
| 484 | // mapped size may exceed the max size temporarily. The file size limit is |
| 485 | // enforced later when the file actually grows. |
| 486 | // |
| 487 | // In practice, this check mainly applies when opening a database with a large |
| 488 | // InitialMmapSize. In all other cases, file growth is already guarded during |
| 489 | // page allocation. |
| 490 | if size > fileSize && runtime.GOOS == "windows" { |
| 491 | db.Logger().Errorf("[GOOS: %s, GOARCH: %s] maximum db size reached, size: %d, db.MaxSize: %d", runtime.GOOS, runtime.GOARCH, size, db.MaxSize) |
| 492 | return berrors.ErrMaxSizeReached |
| 493 | } |
| 494 | } |
| 495 | |
| 496 | if db.Mlock { |
| 497 | // Unlock db memory |
| 498 | if err := db.munlock(fileSize); err != nil { |
| 499 | return err |
| 500 | } |
| 501 | } |
| 502 | |
| 503 | // Dereference all mmap references before unmapping. |
| 504 | if db.rwtx != nil { |
| 505 | db.rwtx.root.dereference() |
| 506 | } |
| 507 | |
| 508 | // Unmap existing data before continuing. |
| 509 | if err = db.munmap(); err != nil { |
| 510 | return err |
| 511 | } |
| 512 | |
| 513 | // Memory-map the data file as a byte slice. |