You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sisyphus/learn.go

110 lines
1.9 KiB
Go

package sisyphus
import (
log "github.com/sirupsen/logrus"
"github.com/boltdb/bolt"
"github.com/retailnext/hllpp"
)
// learnWordlist adds the mail key to the respective word's list
func (m *Mail) learnWordlist(w string, db *bolt.DB) error {
wordKey := "Good"
if m.Junk {
wordKey = "Junk"
}
err := db.Update(func(tx *bolt.Tx) (err error) {
b := tx.Bucket([]byte("Wordlists"))
bucket := b.Bucket([]byte(wordKey))
wordRaw := bucket.Get([]byte(w))
var word *hllpp.HLLPP
if len(wordRaw) == 0 {
word = hllpp.New()
} else {
word, err = hllpp.Unmarshal(wordRaw)
if err != nil {
return err
}
}
word.Add([]byte(m.Key))
err = bucket.Put([]byte(w), word.Marshal())
return err
})
return err
}
// learnStatistics adds the mail key to the respective word's list
func (m *Mail) learnStatistics(db *bolt.DB) error {
err := db.Update(func(tx *bolt.Tx) (err error) {
p := tx.Bucket([]byte("Statistics"))
key := "ProcessedGood"
if m.Junk {
key = "ProcessedJunk"
}
keyRaw := p.Get([]byte(key))
var counter *hllpp.HLLPP
if len(keyRaw) == 0 {
counter = hllpp.New()
} else {
counter, err = hllpp.Unmarshal(keyRaw)
if err != nil {
return err
}
}
counter.Add([]byte(m.Key))
err = p.Put([]byte(key), counter.Marshal())
return err
})
return err
}
// Learn adds the the mail key to the list of words using hyper log log algorithm.
func (m *Mail) Learn(db *bolt.DB, dir Maildir) (err error) {
log.WithFields(log.Fields{
"dir": string(dir),
"mail": m.Key,
}).Info("Learn mail")
err = m.Load(dir)
if err != nil {
return err
}
list, err := m.cleanWordlist()
if err != nil {
return err
}
// Learn words
for _, val := range list {
err = m.learnWordlist(val, db)
if err != nil {
return err
}
}
// Update the statistics counter
err = m.learnStatistics(db)
if err != nil {
return err
}
err = m.Unload(dir)
return err
}