github.com/weaviate/weaviate@v1.24.6/usecases/objects/replication.go (about) 1 // _ _ 2 // __ _____ __ ___ ___ __ _| |_ ___ 3 // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ 4 // \ V V / __/ (_| |\ V /| | (_| | || __/ 5 // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| 6 // 7 // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. 8 // 9 // CONTACT: hello@weaviate.io 10 // 11 12 package objects 13 14 import ( 15 "encoding/json" 16 "fmt" 17 18 "github.com/go-openapi/strfmt" 19 "github.com/weaviate/weaviate/entities/models" 20 "github.com/weaviate/weaviate/entities/storobj" 21 ) 22 23 // VObject is a versioned object for detecting replication inconsistencies 24 type VObject struct { 25 // LatestObject is to most up-to-date version of an object 26 LatestObject *models.Object `json:"object,omitempty"` 27 28 Vector []float32 `json:"vector"` 29 Vectors models.Vectors `json:"vectors"` 30 31 // StaleUpdateTime is the LastUpdateTimeUnix of the stale object sent to the coordinator 32 StaleUpdateTime int64 `json:"updateTime,omitempty"` 33 34 // Version is the most recent incremental version number of the object 35 Version uint64 `json:"version"` 36 } 37 38 // vobjectMarshaler is a helper for the methods implementing encoding.BinaryMarshaler 39 // 40 // Because models.Object has an optimized custom MarshalBinary method, that is what 41 // we want to use when serializing, rather than json.Marshal. This is just a thin 42 // wrapper around the model bytes resulting from the underlying call to MarshalBinary 43 type vobjectMarshaler struct { 44 StaleUpdateTime int64 45 Version uint64 46 Vector []float32 47 Vectors models.Vectors 48 LatestObject []byte 49 } 50 51 func (vo *VObject) MarshalBinary() ([]byte, error) { 52 b := vobjectMarshaler{ 53 StaleUpdateTime: vo.StaleUpdateTime, 54 Vector: vo.Vector, 55 Vectors: vo.Vectors, 56 Version: vo.Version, 57 } 58 if vo.LatestObject != nil { 59 obj, err := vo.LatestObject.MarshalBinary() 60 if err != nil { 61 return nil, fmt.Errorf("marshal object: %w", err) 62 } 63 b.LatestObject = obj 64 } 65 66 return json.Marshal(b) 67 } 68 69 func (vo *VObject) UnmarshalBinary(data []byte) error { 70 var b vobjectMarshaler 71 72 err := json.Unmarshal(data, &b) 73 if err != nil { 74 return err 75 } 76 vo.StaleUpdateTime = b.StaleUpdateTime 77 vo.Vector = b.Vector 78 vo.Vectors = b.Vectors 79 vo.Version = b.Version 80 81 if b.LatestObject != nil { 82 var obj models.Object 83 err = obj.UnmarshalBinary(b.LatestObject) 84 if err != nil { 85 return fmt.Errorf("unmarshal object: %w", err) 86 } 87 vo.LatestObject = &obj 88 } 89 90 return nil 91 } 92 93 // Replica represents a replicated data item 94 type Replica struct { 95 ID strfmt.UUID `json:"id,omitempty"` 96 Deleted bool `json:"deleted"` 97 Object *storobj.Object `json:"object,omitempty"` 98 } 99 100 // robjectMarshaler is a helper for the methods implementing encoding.BinaryMarshaler 101 // 102 // Because *storobj.Object has an optimized custom MarshalBinary method, that is what 103 // we want to use when serializing, rather than json.Marshal. This is just a thin 104 // wrapper around the storobj bytes resulting from the underlying call to MarshalBinary 105 type robjectMarshaler struct { 106 ID strfmt.UUID 107 Deleted bool 108 Object []byte 109 } 110 111 func (r *Replica) MarshalBinary() ([]byte, error) { 112 b := robjectMarshaler{ID: r.ID, Deleted: r.Deleted} 113 if r.Object != nil { 114 obj, err := r.Object.MarshalBinary() 115 if err != nil { 116 return nil, fmt.Errorf("marshal object: %w", err) 117 } 118 b.Object = obj 119 } 120 121 return json.Marshal(b) 122 } 123 124 func (r *Replica) UnmarshalBinary(data []byte) error { 125 var b robjectMarshaler 126 127 err := json.Unmarshal(data, &b) 128 if err != nil { 129 return err 130 } 131 r.ID = b.ID 132 r.Deleted = b.Deleted 133 134 if b.Object != nil { 135 var obj storobj.Object 136 err = obj.UnmarshalBinary(b.Object) 137 if err != nil { 138 return fmt.Errorf("unmarshal object: %w", err) 139 } 140 r.Object = &obj 141 } 142 143 return nil 144 } 145 146 type Replicas []Replica 147 148 func (ro Replicas) MarshalBinary() ([]byte, error) { 149 ms := make([]robjectMarshaler, len(ro)) 150 151 for i, obj := range ro { 152 m := robjectMarshaler{ID: obj.ID, Deleted: obj.Deleted} 153 if obj.Object != nil { 154 b, err := obj.Object.MarshalBinary() 155 if err != nil { 156 return nil, fmt.Errorf("marshal object %q: %w", obj.ID, err) 157 } 158 m.Object = b 159 } 160 ms[i] = m 161 } 162 163 return json.Marshal(ms) 164 } 165 166 func (ro *Replicas) UnmarshalBinary(data []byte) error { 167 var ms []robjectMarshaler 168 169 err := json.Unmarshal(data, &ms) 170 if err != nil { 171 return err 172 } 173 174 reps := make(Replicas, len(ms)) 175 for i, m := range ms { 176 rep := Replica{ID: m.ID, Deleted: m.Deleted} 177 if m.Object != nil { 178 var obj storobj.Object 179 err = obj.UnmarshalBinary(m.Object) 180 if err != nil { 181 return fmt.Errorf("unmarshal object %q: %w", m.ID, err) 182 } 183 rep.Object = &obj 184 } 185 reps[i] = rep 186 } 187 188 *ro = reps 189 return nil 190 } 191 192 // UpdateTime return update time if it exists and 0 otherwise 193 func (r Replica) UpdateTime() int64 { 194 if r.Object != nil { 195 return r.Object.LastUpdateTimeUnix() 196 } 197 return 0 198 }