rc1
This commit is contained in:
72
freelist/freelist.go
Normal file
72
freelist/freelist.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package freelist
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/RoaringBitmap/roaring/v2"
|
||||
)
|
||||
|
||||
type FreeList struct {
|
||||
mutex sync.Mutex
|
||||
free *roaring.Bitmap
|
||||
reserved *roaring.Bitmap
|
||||
}
|
||||
|
||||
func New() *FreeList {
|
||||
return &FreeList{
|
||||
free: roaring.New(),
|
||||
reserved: roaring.New(),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FreeList) Restore(serialized []byte) error {
|
||||
err := s.free.UnmarshalBinary(serialized)
|
||||
if err != nil {
|
||||
return fmt.Errorf("UnmarshalBinary: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *FreeList) AddPages(pageNumbers []uint32) {
|
||||
if len(pageNumbers) == 0 {
|
||||
return
|
||||
}
|
||||
s.mutex.Lock()
|
||||
s.free.AddMany(pageNumbers)
|
||||
s.mutex.Unlock()
|
||||
}
|
||||
|
||||
// ReserveDataPage - аллокатор резервирует страницу, но не удаляет до визова
|
||||
// DeleteFromFree, ибо транзакция может не завершится, а между віделением страници
|
||||
// и падением транзакции - будет создан init файл.
|
||||
func (s *FreeList) ReservePage() (pageNo uint32) {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
|
||||
if s.free.IsEmpty() {
|
||||
return
|
||||
}
|
||||
pageNo = s.free.Minimum()
|
||||
s.free.Remove(pageNo)
|
||||
s.reserved.Add(pageNo)
|
||||
return
|
||||
}
|
||||
|
||||
// Удаляет ранее зарезервированные страницы
|
||||
func (s *FreeList) DeletePages(pageNumbers []uint32) {
|
||||
s.mutex.Lock()
|
||||
for _, pageNo := range pageNumbers {
|
||||
s.reserved.Remove(pageNo)
|
||||
s.free.Remove(pageNo) // прокрута TransactionLog
|
||||
}
|
||||
s.mutex.Unlock()
|
||||
}
|
||||
|
||||
func (s *FreeList) Serialize() ([]byte, error) {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
tmp := roaring.Or(s.free, s.reserved)
|
||||
tmp.RunOptimize()
|
||||
return tmp.ToBytes()
|
||||
}
|
||||
Reference in New Issue
Block a user