func (db *DB) _raw_ssttlat_put(ns byte, key []byte, ttlat uint64) bool { if ttlat == 0 { return true } key = skv.RawNsKeyConcat(ns, key) batch := new(leveldb.Batch) // if prev := db.RawGet(skv.RawTtlEntry(key)); prev.Status == skv.ReplyOK { if prev_ttlat := dbutil.BytesToUint64(prev.Bytes()); prev_ttlat != ttlat { batch.Delete(skv.RawTtlQueue(key, prev_ttlat)) } } // batch.Put(skv.RawTtlQueue(key, ttlat), []byte{}) // batch.Put(skv.RawTtlEntry(key), dbutil.Uint64ToBytes(ttlat)) if err := db.ldb.Write(batch, nil); err != nil { return false } return true }
func (db *DB) ttl_worker() { go func() { for { ls := db._raw_ssttlat_range(0, dbutil.MetaTimeNow(), _ttl_worker_limit).Hash() for _, v := range ls { batch := new(leveldb.Batch) if dbutil.BytesToUint64(db.RawGet(skv.RawTtlEntry(v.Key[9:])).Bytes()) == v.Uint64() { batch.Delete(skv.RawTtlEntry(v.Key[9:])) switch v.Key[9] { case skv.NsObjectEntry: db.ObjectDel(string(v.Key[10:])) case skv.NsKvEntry: batch.Delete(v.Key[9:]) } } batch.Delete(v.Key) db.ldb.Write(batch, nil) } if uint64(len(ls)) < _ttl_worker_limit { time.Sleep(_ttl_worker_sleep) } } }() }
func (db *DB) _raw_ssttl_get(ns byte, key []byte) *skv.Reply { key = skv.RawNsKeyConcat(ns, key) rpl, ttl := skv.NewReply(""), int64(0) if ttlat := dbutil.BytesToUint64(db.RawGet(skv.RawTtlEntry(key)).Bytes()); ttlat > 0 { ttl = (dbutil.MetaTimeParse(ttlat).UnixNano() - time.Now().UTC().UnixNano()) / 1e6 } if ttl < 0 { ttl = 0 } rpl.Data = append(rpl.Data, []byte(strconv.FormatInt(ttl, 10))) return rpl }