getPageSizeFromSecondMeta reads the pageSize from the second meta page
()
| 380 | |
| 381 | // getPageSizeFromSecondMeta reads the pageSize from the second meta page |
| 382 | func (db *DB) getPageSizeFromSecondMeta() (int, bool, error) { |
| 383 | var ( |
| 384 | fileSize int64 |
| 385 | metaCanRead bool |
| 386 | ) |
| 387 | |
| 388 | // get the db file size |
| 389 | if info, err := db.file.Stat(); err != nil { |
| 390 | return 0, metaCanRead, err |
| 391 | } else { |
| 392 | fileSize = info.Size() |
| 393 | } |
| 394 | |
| 395 | // We need to read the second meta page, so we should skip the first page; |
| 396 | // but we don't know the exact page size yet, it's chicken & egg problem. |
| 397 | // The solution is to try all the possible page sizes, which starts from 1KB |
| 398 | // and until 16MB (1024<<14) or the end of the db file |
| 399 | // |
| 400 | // TODO: should we support larger page size? |
| 401 | for i := 0; i <= 14; i++ { |
| 402 | var buf [0x1000]byte |
| 403 | var pos int64 = 1024 << uint(i) |
| 404 | if pos >= fileSize-1024 { |
| 405 | break |
| 406 | } |
| 407 | bw, err := db.file.ReadAt(buf[:], pos) |
| 408 | if (err == nil && bw == len(buf)) || (err == io.EOF && int64(bw) == (fileSize-pos)) { |
| 409 | metaCanRead = true |
| 410 | if m := db.pageInBuffer(buf[:], 0).Meta(); m.Validate() == nil { |
| 411 | return int(m.PageSize()), metaCanRead, nil |
| 412 | } |
| 413 | } |
| 414 | } |
| 415 | |
| 416 | return 0, metaCanRead, berrors.ErrInvalid |
| 417 | } |
| 418 | |
| 419 | // loadFreelist reads the freelist if it is synced, or reconstructs it |
| 420 | // by scanning the DB if it is not synced. It assumes there are no |
no test coverage detected