MCPcopy Create free account
hub / github.com/IceFireDB/IceFireDB / cmdRPOPLPUSH

Function cmdRPOPLPUSH

lists.go:197–293  ·  view source on GitHub ↗
(m uhaha.Machine, args []string)

Source from the content-addressed store, hash-verified

195}
196
197func cmdRPOPLPUSH(m uhaha.Machine, args []string) (interface{}, error) {
198
199 if len(args) != 3 {
200 return nil, uhaha.ErrWrongNumArgs
201 }
202 source, dest := []byte(args[1]), []byte(args[2])
203
204 var ttl int64 = -1
205 var expireTime int64 = -1
206 if bytes.Compare(source, dest) == 0 {
207 var err error
208 ttl, err = ldb.LTTL(source)
209 if err != nil {
210 return nil, err
211 }
212 if ttl != -1 {
213 expireTime = m.Now().Unix() + ttl
214 }
215 }
216
217 // Special handling for same source and destination (rotation)
218 if bytes.Compare(source, dest) == 0 {
219 // Use global mutex for same source/destination operations
220 // to ensure absolute atomicity
221 sameKeyMutex.Lock()
222 defer sameKeyMutex.Unlock()
223
224 // Get the last element
225 data, err := ldb.RPop(source)
226 if err != nil {
227 return nil, err
228 }
229
230 if data == nil {
231 return nil, nil
232 }
233
234 // Push it back to the front
235 if _, err := ldb.LPush(source, data); err != nil {
236 // If push fails, revert the pop
237 ldb.RPush(source, data)
238 return nil, err
239 }
240
241 //reset ttl using absolute time
242 if expireTime != -1 {
243 ldb.LExpireAt(source, expireTime)
244 }
245
246 return data, nil
247 }
248
249 // For different source and destination, we need to lock both keys
250 // to prevent deadlocks, we always lock in a consistent order
251 var firstKey, secondKey []byte
252 if bytes.Compare(source, dest) < 0 {
253 firstKey = source
254 secondKey = dest

Callers

nothing calls this directly

Calls 2

keyMutexIndexFunction · 0.85
CompareMethod · 0.45

Tested by

no test coverage detected