Fix data corruption bug (overwrite data)
This commit is contained in:
		@@ -4,6 +4,7 @@ Replicated in-memory database and file store.
 | 
			
		||||
 | 
			
		||||
## TODO
 | 
			
		||||
 | 
			
		||||
* [ ] mdb: Tests for using `nil` snapshots ?
 | 
			
		||||
* [ ] mdb: tests for sanitize and validate functions
 | 
			
		||||
* [ ] Test: lib/wal iterator w/ corrupt file (random corruptions)
 | 
			
		||||
* [ ] Test: lib/wal io.go
 | 
			
		||||
 
 | 
			
		||||
@@ -51,6 +51,10 @@ func (f *freeList) Push(pages ...uint64) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *freeList) SetNextPage(nextPage uint64) {
 | 
			
		||||
	f.nextPage = nextPage
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *freeList) Pop(count int, out []uint64) []uint64 {
 | 
			
		||||
	out = out[:0]
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -13,14 +13,19 @@ type Index struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewIndex(f *File) (*Index, error) {
 | 
			
		||||
	maxPage, err := f.maxPage()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	idx := &Index{
 | 
			
		||||
		fList: newFreeList(0),
 | 
			
		||||
		fList: newFreeList(maxPage),
 | 
			
		||||
		aList: *newAllocList(),
 | 
			
		||||
		seen:  map[[2]uint64]struct{}{},
 | 
			
		||||
		mask:  []bool{},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err := f.iterate(func(pageID uint64, page dataPage) error {
 | 
			
		||||
	err = f.iterate(func(pageID uint64, page dataPage) error {
 | 
			
		||||
		header := page.Header()
 | 
			
		||||
		switch header.PageType {
 | 
			
		||||
		case pageTypeHead:
 | 
			
		||||
 
 | 
			
		||||
@@ -134,6 +134,21 @@ func (pf *File) writePage(page dataPage, id uint64) error {
 | 
			
		||||
// Reading
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
func (pf *File) maxPage() (uint64, error) {
 | 
			
		||||
	fi, err := pf.f.Stat()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, errs.IO.WithErr(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fileSize := fi.Size()
 | 
			
		||||
	if fileSize%pageSize != 0 {
 | 
			
		||||
		return 0, errs.Corrupt.WithMsg("File size isn't a multiple of page size.")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	maxPage := uint64(fileSize / pageSize)
 | 
			
		||||
	return maxPage, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (pf *File) iterate(each func(pageID uint64, page dataPage) error) error {
 | 
			
		||||
	pf.lock.RLock()
 | 
			
		||||
	defer pf.lock.RUnlock()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user