Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve conflict #367

Merged
merged 2 commits into from
Dec 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion db.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"hash/fnv"
"io"
"os"
"runtime"
"sort"
Expand Down Expand Up @@ -377,7 +378,8 @@ func (db *DB) getPageSizeFromSecondMeta() (int, bool, error) {
if pos >= fileSize-1024 {
break
}
if bw, err := db.file.ReadAt(buf[:], pos); err == nil && bw == len(buf) {
bw, err := db.file.ReadAt(buf[:], pos)
if (err == nil && bw == len(buf)) || (err == io.EOF && int64(bw) == (fileSize-pos)) {
metaCanRead = true
if m := db.pageInBuffer(buf[:], 0).meta(); m.validate() == nil {
return int(m.pageSize), metaCanRead, nil
Expand Down
60 changes: 19 additions & 41 deletions db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,14 +215,10 @@ func TestOpen_ErrChecksum(t *testing.T) {
// The page size is expected to be the OS's page size in this case.
func TestOpen_ReadPageSize_FromMeta1_OS(t *testing.T) {
// Create empty database.
db := MustOpenDB()
db := btesting.MustCreateDB(t)
path := db.Path()
defer db.MustClose()

// Close database.
if err := db.DB.Close(); err != nil {
t.Fatal(err)
}
// Close the database
db.MustClose()

// Read data file.
buf, err := os.ReadFile(path)
Expand All @@ -238,16 +234,8 @@ func TestOpen_ReadPageSize_FromMeta1_OS(t *testing.T) {
}

// Reopen data file.
if db, err := bolt.Open(path, 0666, nil); err != nil {
t.Fatalf("unexpected error: %s", err)
} else {
if db.Info().PageSize != os.Getpagesize() {
t.Fatalf("The page size is expected to be %d, but actually is %d", os.Getpagesize(), db.Info().PageSize)
}
if err := db.Close(); err != nil {
panic(err)
}
}
db = btesting.MustOpenDBWithOption(t, path, nil)
require.Equalf(t, os.Getpagesize(), db.Info().PageSize, "check page size failed")
}

// Ensure that it can read the page size from the second meta page if the first one is invalid.
Expand All @@ -256,40 +244,30 @@ func TestOpen_ReadPageSize_FromMeta1_Given(t *testing.T) {
// test page size from 1KB (1024<<0) to 16MB(1024<<14)
for i := 0; i <= 14; i++ {
givenPageSize := 1024 << uint(i)
t.Logf("Testing page size %d", givenPageSize)
// Create empty database.
db := MustOpenWithOption(&bolt.Options{PageSize: givenPageSize})
db := btesting.MustCreateDBWithOption(t, &bolt.Options{PageSize: givenPageSize})
path := db.Path()
defer db.MustClose()

// Close database.
if err := db.DB.Close(); err != nil {
t.Fatal(err)
}
// Close the database
db.MustClose()

// Read data file.
buf, err := os.ReadFile(path)
if err != nil {
t.Fatal(err)
}
require.NoError(t, err)

// Rewrite meta pages.
meta0 := (*meta)(unsafe.Pointer(&buf[pageHeaderSize]))
meta0.pgid++
if err := os.WriteFile(path, buf, 0666); err != nil {
t.Fatal(err)
if i%3 == 0 {
t.Logf("#%d: Intentionally corrupt the first meta page for pageSize %d", i, givenPageSize)
meta0 := (*meta)(unsafe.Pointer(&buf[pageHeaderSize]))
meta0.pgid++
err = os.WriteFile(path, buf, 0666)
require.NoError(t, err)
}

// Reopen data file.
if db, err := bolt.Open(path, 0666, &bolt.Options{PageSize: givenPageSize}); err != nil {
t.Fatalf("unexpected error: %s", err)
} else {
if db.Info().PageSize != givenPageSize {
t.Fatalf("The page size is expected to be %d, but actually is %d", givenPageSize, db.Info().PageSize)
}
if err := db.Close(); err != nil {
panic(err)
}
}
db = btesting.MustOpenDBWithOption(t, path, nil)
require.Equalf(t, givenPageSize, db.Info().PageSize, "check page size failed")
db.MustClose()
}
}

Expand Down