// /futriis/pkg/types/types.go // Пакет types определяет основные структуры данных СУБД Futriis. // Содержит определения для тапплов (баз данных), слайсов (таблиц) и кортежей (записей). // Использует wait-free подход с атомарными операциями вместо мьютексов. package types import ( "sync/atomic" "time" "unsafe" ) // Tapple представляет базу данных (контейнер верхнего уровня) с wait-free доступом type Tapple struct { Name string slices unsafe.Pointer // Атомарный указатель на map[string]*Slice CreatedAt time.Time UpdatedAt time.Time } // NewTapple создаёт новый таппл с wait-free доступом func NewTapple(name string) *Tapple { slices := make(map[string]*Slice) return &Tapple{ Name: name, slices: unsafe.Pointer(&slices), CreatedAt: time.Now(), UpdatedAt: time.Now(), } } // GetSlices атомарно получает карту слайсов func (t *Tapple) GetSlices() map[string]*Slice { ptr := atomic.LoadPointer(&t.slices) return *(*map[string]*Slice)(ptr) } // GetSlice атомарно получает слайс по имени func (t *Tapple) GetSlice(name string) (*Slice, bool) { slices := t.GetSlices() slice, exists := slices[name] return slice, exists } // PutSlice атомарно добавляет или обновляет слайс func (t *Tapple) PutSlice(name string, slice *Slice) { for { oldPtr := atomic.LoadPointer(&t.slices) oldSlices := *(*map[string]*Slice)(oldPtr) // Создаём новую карту newSlices := make(map[string]*Slice) for k, v := range oldSlices { newSlices[k] = v } newSlices[name] = slice // Пытаемся атомарно обновить if atomic.CompareAndSwapPointer(&t.slices, oldPtr, unsafe.Pointer(&newSlices)) { t.UpdatedAt = time.Now() break } } } // DeleteSlice атомарно удаляет слайс func (t *Tapple) DeleteSlice(name string) bool { for { oldPtr := atomic.LoadPointer(&t.slices) oldSlices := *(*map[string]*Slice)(oldPtr) if _, exists := oldSlices[name]; !exists { return false } // Создаём новую карту без удаляемого слайса newSlices := make(map[string]*Slice) for k, v := range oldSlices { if k != name { newSlices[k] = v } } // Пытаемся атомарно обновить if atomic.CompareAndSwapPointer(&t.slices, oldPtr, unsafe.Pointer(&newSlices)) { t.UpdatedAt = time.Now() return true } } } // Slice представляет таблицу (контейнер для кортежей) с wait-free доступом type Slice struct { Name string tuples unsafe.Pointer // Атомарный указатель на map[string]*Tuple CreatedAt time.Time UpdatedAt time.Time } // NewSlice создаёт новый слайс с wait-free доступом func NewSlice(name string) *Slice { tuples := make(map[string]*Tuple) return &Slice{ Name: name, tuples: unsafe.Pointer(&tuples), CreatedAt: time.Now(), UpdatedAt: time.Now(), } } // GetTuples атомарно получает карту кортежей func (s *Slice) GetTuples() map[string]*Tuple { ptr := atomic.LoadPointer(&s.tuples) return *(*map[string]*Tuple)(ptr) } // GetTuple атомарно получает кортеж по ID func (s *Slice) GetTuple(id string) (*Tuple, bool) { tuples := s.GetTuples() tuple, exists := tuples[id] return tuple, exists } // PutTuple атомарно добавляет или обновляет кортеж func (s *Slice) PutTuple(id string, tuple *Tuple) { for { oldPtr := atomic.LoadPointer(&s.tuples) oldTuples := *(*map[string]*Tuple)(oldPtr) // Создаём новую карту newTuples := make(map[string]*Tuple) for k, v := range oldTuples { newTuples[k] = v } newTuples[id] = tuple // Пытаемся атомарно обновить if atomic.CompareAndSwapPointer(&s.tuples, oldPtr, unsafe.Pointer(&newTuples)) { s.UpdatedAt = time.Now() break } } } // DeleteTuple атомарно удаляет кортеж func (s *Slice) DeleteTuple(id string) bool { for { oldPtr := atomic.LoadPointer(&s.tuples) oldTuples := *(*map[string]*Tuple)(oldPtr) if _, exists := oldTuples[id]; !exists { return false } // Создаём новую карту без удаляемого кортежа newTuples := make(map[string]*Tuple) for k, v := range oldTuples { if k != id { newTuples[k] = v } } // Пытаемся атомарно обновить if atomic.CompareAndSwapPointer(&s.tuples, oldPtr, unsafe.Pointer(&newTuples)) { s.UpdatedAt = time.Now() return true } } } // Tuple представляет кортеж (запись) type Tuple struct { ID string Fields map[string]interface{} CreatedAt time.Time UpdatedAt time.Time } // NewTuple создаёт новый кортеж func NewTuple(id string) *Tuple { return &Tuple{ ID: id, Fields: make(map[string]interface{}), CreatedAt: time.Now(), UpdatedAt: time.Now(), } }