wp
This commit is contained in:
152
atree/io.go
152
atree/io.go
@@ -34,20 +34,31 @@ func (s *Atree) DeletePages(pageNumbers []uint32) {
|
||||
}
|
||||
|
||||
func (s *Atree) fetchIndexPage(pageNo uint32) ([]byte, error) {
|
||||
return s.fetchPage(pageNo, PageTypeIndex)
|
||||
buf, err := s.fetchPage(pageNo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if buf[pageTypeIdx] != PageTypeIndex {
|
||||
return nil, fmt.Errorf("wrong pageType %d instead of %d", buf[pageTypeIdx], PageTypeIndex)
|
||||
}
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func (s *Atree) fetchDataPage(pageNo uint32) ([]byte, error) {
|
||||
return s.fetchPage(pageNo, PageTypeData)
|
||||
buf, err := s.fetchPage(pageNo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if buf[pageTypeIdx] != PageTypeIndex {
|
||||
return nil, fmt.Errorf("wrong pageType %d instead of %d", buf[pageTypeIdx], PageTypeIndex)
|
||||
}
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func (s *Atree) fetchPage(pageNo uint32, pageTypeIdx byte) ([]byte, error) {
|
||||
func (s *Atree) fetchPage(pageNo uint32) ([]byte, error) {
|
||||
s.mutex.Lock()
|
||||
p, ok := s.pages[pageNo]
|
||||
if ok {
|
||||
if p.Buf[pageTypeIdx] != pageTypeIdx {
|
||||
return nil, fmt.Errorf("wrong pageType %d instead of %d", p.Buf[pageTypeIdx], pageTypeIdx)
|
||||
}
|
||||
p.ReferenceCount++
|
||||
s.mutex.Unlock()
|
||||
return p.Buf, nil
|
||||
@@ -93,23 +104,28 @@ func (s *Atree) releasePage(pageNo uint32) {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Atree) allocPageNumber() (uint32, bool) {
|
||||
// fix
|
||||
return 0, true
|
||||
}
|
||||
|
||||
func (s *Atree) allocPage() AllocatedPage {
|
||||
var (
|
||||
allocated = AllocatedPage{
|
||||
Data: make([]byte, PageSize),
|
||||
}
|
||||
)
|
||||
allocated.PageNo = s.freelist.ReservePage()
|
||||
//allocated.PageNo = s.freelist.ReservePage()
|
||||
s.mutex.Lock()
|
||||
if allocated.PageNo > 0 {
|
||||
allocated.IsReused = true
|
||||
} else {
|
||||
if s.allocatedPagesQty == math.MaxUint32 {
|
||||
qb.Abort(qb.MaxAtreeSizeExceeded, errors.New("no space in Atree index"))
|
||||
}
|
||||
s.allocatedPagesQty++
|
||||
allocated.PageNo = s.allocatedPagesQty
|
||||
}
|
||||
// if allocated.PageNo > 0 {
|
||||
// allocated.IsReused = true
|
||||
// } else {
|
||||
// if s.allocatedPagesQty == math.MaxUint32 {
|
||||
// qb.Abort(qb.MaxAtreeSizeExceeded, errors.New("no space in Atree index"))
|
||||
// }
|
||||
// s.allocatedPagesQty++
|
||||
// allocated.PageNo = s.allocatedPagesQty
|
||||
// }
|
||||
|
||||
// s.pages[allocated.PageNo] = &_page{
|
||||
// // fix pageType
|
||||
@@ -241,61 +257,61 @@ func (s *Atree) readPages() {
|
||||
|
||||
// WRITE
|
||||
|
||||
func (s *Atree) pageWriter() {
|
||||
for {
|
||||
select {
|
||||
case <-s.writeSignalCh:
|
||||
err := s.writeTasks()
|
||||
if err != nil {
|
||||
qb.Abort(qb.WriteToAtreeFailed, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// func (s *Atree) pageWriter() {
|
||||
// for {
|
||||
// select {
|
||||
// case <-s.writeSignalCh:
|
||||
// err := s.writeTasks()
|
||||
// if err != nil {
|
||||
// qb.Abort(qb.WriteToAtreeFailed, err)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
type WriteTask struct {
|
||||
WaitCh chan struct{}
|
||||
Pages []PageToWrite
|
||||
}
|
||||
// type WriteTask struct {
|
||||
// WaitCh chan struct{}
|
||||
// Pages []PageToWrite
|
||||
// }
|
||||
|
||||
func (s *Atree) appendWriteTaskToQueue(task WriteTask) {
|
||||
s.mutex.Lock()
|
||||
s.writeTasksQueue = append(s.writeTasksQueue, task)
|
||||
s.mutex.Unlock()
|
||||
// func (s *Atree) appendWriteTaskToQueue(task WriteTask) {
|
||||
// s.mutex.Lock()
|
||||
// s.writeTasksQueue = append(s.writeTasksQueue, task)
|
||||
// s.mutex.Unlock()
|
||||
|
||||
select {
|
||||
case s.writeSignalCh <- struct{}{}:
|
||||
default:
|
||||
}
|
||||
}
|
||||
// select {
|
||||
// case s.writeSignalCh <- struct{}{}:
|
||||
// default:
|
||||
// }
|
||||
// }
|
||||
|
||||
func (s *Atree) writeTasks() error {
|
||||
s.mutex.Lock()
|
||||
tasks := s.writeTasksQueue
|
||||
s.writeTasksQueue = nil
|
||||
s.mutex.Unlock()
|
||||
// func (s *Atree) writeTasks() error {
|
||||
// s.mutex.Lock()
|
||||
// tasks := s.writeTasksQueue
|
||||
// s.writeTasksQueue = nil
|
||||
// s.mutex.Unlock()
|
||||
|
||||
for _, task := range tasks {
|
||||
for _, p := range task.Pages {
|
||||
if len(p.Data) != PageSize {
|
||||
return fmt.Errorf("wrong page %d size: %d",
|
||||
p.PageNo, len(p.Data))
|
||||
}
|
||||
bin.PutUint32(p.Data[crc32Idx:], calcChecksum(p.Data[:crc32Idx]))
|
||||
// for _, task := range tasks {
|
||||
// for _, p := range task.Pages {
|
||||
// if len(p.Data) != PageSize {
|
||||
// return fmt.Errorf("wrong page %d size: %d",
|
||||
// p.PageNo, len(p.Data))
|
||||
// }
|
||||
// bin.PutUint32(p.Data[crc32Idx:], calcChecksum(p.Data[:crc32Idx]))
|
||||
|
||||
off := (p.PageNo - 1) * PageSize
|
||||
n, err := s.file.WriteAt(p.Data, int64(off))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if n != len(p.Data) {
|
||||
return fmt.Errorf("write %d instead of %d", n, len(p.Data))
|
||||
}
|
||||
}
|
||||
close(task.WaitCh)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// off := (p.PageNo - 1) * PageSize
|
||||
// n, err := s.file.WriteAt(p.Data, int64(off))
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if n != len(p.Data) {
|
||||
// return fmt.Errorf("write %d instead of %d", n, len(p.Data))
|
||||
// }
|
||||
// }
|
||||
// close(task.WaitCh)
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
|
||||
// IO
|
||||
|
||||
@@ -339,9 +355,9 @@ func openFile(fileName string, pageSize int) (_ *os.File, _ uint32, err error) {
|
||||
return file, uint32(allocatedPagesQty), nil
|
||||
}
|
||||
|
||||
func (s *Atree) ApplyREDO(task WriteTask) {
|
||||
s.appendWriteTaskToQueue(task)
|
||||
}
|
||||
// func (s *Atree) ApplyREDO(task WriteTask) {
|
||||
// s.appendWriteTaskToQueue(task)
|
||||
// }
|
||||
|
||||
func (s *Atree) verifyCRC(data []byte, pageSize int) error {
|
||||
var (
|
||||
|
||||
Reference in New Issue
Block a user