diff --git a/core/generics/model/mutable.go b/core/generics/model/mutable.go index 69cc76038..cb8bd83cb 100644 --- a/core/generics/model/mutable.go +++ b/core/generics/model/mutable.go @@ -18,7 +18,7 @@ import ( type Mutable[OuterModelType any, OuterModelPtrType PtrType[OuterModelType, InnerModelType], InnerModelType any] struct { M InnerModelType - bytes []byte + bytes *[]byte // using a pointer here because serix uses reflection which creates a copy of the object cacheBytes bool bytesMutex *sync.RWMutex @@ -49,6 +49,7 @@ func (m *Mutable[OuterModelType, OuterModelPtrType, InnerModelType]) New(innerMo func (m *Mutable[OuterModelType, OuterModelPtrType, InnerModelType]) Init() { m.RWMutex = new(sync.RWMutex) m.bytesMutex = new(sync.RWMutex) + m.bytes = new([]byte) } // InnerModel returns the inner Model that holds the data. @@ -75,7 +76,7 @@ func (m *Mutable[OuterModelType, OuterModelPtrType, InnerModelType]) InvalidateB m.bytesMutex.Lock() defer m.bytesMutex.Unlock() - m.bytes = nil + m.bytes = new([]byte) } // FromBytes deserializes a model from a byte slice. @@ -98,7 +99,7 @@ func (m *Mutable[OuterModelType, OuterModelPtrType, InnerModelType]) FromBytes(b defer m.bytesMutex.Unlock() // Store the bytes we decoded to avoid any future Encode calls. - m.bytes = bytes[:consumedBytes] + *m.bytes = bytes[:consumedBytes] } return consumedBytes, nil @@ -111,10 +112,10 @@ func (m *Mutable[OuterModelType, OuterModelPtrType, InnerModelType]) Bytes() (by // Return the encoded bytes if we already encoded this object to bytes or decoded it from bytes. m.bytesMutex.RLock() - if m.cacheBytes && len(m.bytes) > 0 { + if m.cacheBytes && m.bytes != nil && len(*m.bytes) > 0 { defer m.bytesMutex.RUnlock() - return m.bytes, nil + return *m.bytes, nil } m.bytesMutex.RUnlock() @@ -131,7 +132,7 @@ func (m *Mutable[OuterModelType, OuterModelPtrType, InnerModelType]) Bytes() (by defer m.bytesMutex.Unlock() // Store the encoded bytes to avoid future calls to Encode. - m.bytes = encodedBytes + *m.bytes = encodedBytes } return encodedBytes, err diff --git a/core/generics/model/storable.go b/core/generics/model/storable.go index fb2e71300..8d31aabdb 100644 --- a/core/generics/model/storable.go +++ b/core/generics/model/storable.go @@ -23,7 +23,7 @@ type Storable[IDType, OuterModelType any, OuterModelPtrType PtrType[OuterModelTy idMutex *sync.RWMutex M InnerModelType - bytes []byte + bytes *[]byte // using a pointer here because serix uses reflection which creates a copy of the object cacheBytes bool bytesMutex *sync.RWMutex @@ -60,6 +60,7 @@ func (s *Storable[IDType, OuterModelType, OuterModelPtrType, InnerModelType]) In s.idMutex = new(sync.RWMutex) s.bytesMutex = new(sync.RWMutex) + s.bytes = new([]byte) s.RWMutex = new(sync.RWMutex) s.StorableObjectFlags = new(objectstorage.StorableObjectFlags) @@ -127,7 +128,7 @@ func (s *Storable[IDType, OuterModelType, OuterModelPtrType, InnerModelType]) Fr s.bytesMutex.Lock() defer s.bytesMutex.Unlock() // Store the bytes we decoded to avoid any future Encode calls. - s.bytes = bytes[:consumedBytes] + *s.bytes = bytes[:consumedBytes] } return consumedBytes, nil @@ -140,10 +141,10 @@ func (s *Storable[IDType, OuterModelType, OuterModelPtrType, InnerModelType]) By // Return the encoded bytes if we already encoded this object to bytes or decoded it from bytes. s.bytesMutex.RLock() - if s.cacheBytes && len(s.bytes) > 0 { + if s.cacheBytes && s.bytes != nil && len(*s.bytes) > 0 { defer s.bytesMutex.RUnlock() - return s.bytes, nil + return *s.bytes, nil } s.bytesMutex.RUnlock() @@ -160,7 +161,7 @@ func (s *Storable[IDType, OuterModelType, OuterModelPtrType, InnerModelType]) By defer s.bytesMutex.Unlock() // Store the encoded bytes to avoid future calls to Encode. - s.bytes = encodedBytes + *s.bytes = encodedBytes } return encodedBytes, err @@ -171,7 +172,7 @@ func (s *Storable[IDType, OuterModelType, OuterModelPtrType, InnerModelType]) In s.bytesMutex.Lock() defer s.bytesMutex.Unlock() - s.bytes = nil + s.bytes = new([]byte) } // FromObjectStorage deserializes a model from the object storage.