спеціалізована СУБД для зберігання та обробки показань датчиків та лічильників
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
diploma/freelist/freelist.go

72 lines
1.6 KiB

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()
}