custom expired config event

This commit is contained in:
Josh Baker 2016-09-30 16:59:57 -07:00
parent 454b94d04a
commit f6366c8b4b
1 changed files with 33 additions and 16 deletions

View File

@ -117,6 +117,10 @@ type Config struct {
// AutoShrinkDisabled turns off automatic background shrinking // AutoShrinkDisabled turns off automatic background shrinking
AutoShrinkDisabled bool AutoShrinkDisabled bool
// OnExpired is used to custom handle the deletion option when a key
// has been expired.
OnExpired func(keys []string)
} }
// exctx is a simple b-tree context for ordering by expiration. // exctx is a simple b-tree context for ordering by expiration.
@ -520,7 +524,10 @@ func (db *DB) backgroundManager() {
var shrink bool var shrink bool
// Open a standard view. This will take a full lock of the // Open a standard view. This will take a full lock of the
// database thus allowing for access to anything we need. // database thus allowing for access to anything we need.
var onExpired func([]string)
var expired []string
err := db.Update(func(tx *Tx) error { err := db.Update(func(tx *Tx) error {
onExpired = db.config.OnExpired
if db.persist && !db.config.AutoShrinkDisabled { if db.persist && !db.config.AutoShrinkDisabled {
pos, err := db.file.Seek(0, 1) pos, err := db.file.Seek(0, 1)
if err != nil { if err != nil {
@ -533,35 +540,45 @@ func (db *DB) backgroundManager() {
} }
} }
// produce a list of expired items that need removing // produce a list of expired items that need removing
var remove []*dbItem
db.exps.AscendLessThan(&dbItem{ db.exps.AscendLessThan(&dbItem{
opts: &dbItemOpts{ex: true, exat: time.Now()}, opts: &dbItemOpts{ex: true, exat: time.Now()},
}, func(item btree.Item) bool { }, func(item btree.Item) bool {
remove = append(remove, item.(*dbItem)) expired = append(expired, item.(*dbItem).key)
return true return true
}) })
for _, item := range remove { if onExpired == nil {
if _, err := tx.Delete(item.key); err != nil { for _, key := range expired {
// it's ok to get a "not found" because the if _, err := tx.Delete(key); err != nil {
// 'Delete' method reports "not found" for // it's ok to get a "not found" because the
// expired items. // 'Delete' method reports "not found" for
if err != ErrNotFound { // expired items.
return err if err != ErrNotFound {
return err
}
} }
} }
} }
// execute a disk sync.
if db.persist && db.config.SyncPolicy == EverySecond &&
flushes != db.flushes {
_ = db.file.Sync()
flushes = db.flushes
}
return nil return nil
}) })
if err == ErrDatabaseClosed { if err == ErrDatabaseClosed {
break break
} }
// send expired event, if needed
if onExpired != nil && len(expired) > 0 {
onExpired(expired)
}
// execute a disk sync, if needed
func() {
db.mu.Lock()
defer db.mu.Unlock()
if db.persist && db.config.SyncPolicy == EverySecond &&
flushes != db.flushes {
_ = db.file.Sync()
flushes = db.flushes
}
}()
if shrink { if shrink {
if err = db.Shrink(); err != nil { if err = db.Shrink(); err != nil {
if err == ErrDatabaseClosed { if err == ErrDatabaseClosed {