mirror of https://github.com/curusarn/resh
parent
baeb955841
commit
8824893b15
@ -0,0 +1,85 @@ |
||||
package main |
||||
|
||||
import ( |
||||
"math" |
||||
"sort" |
||||
"strconv" |
||||
|
||||
"github.com/curusarn/resh/common" |
||||
) |
||||
|
||||
type strategyDynamicRecordDistance struct { |
||||
history []common.EnrichedRecord |
||||
distParams common.DistParams |
||||
pwdHistogram map[string]int |
||||
realPwdHistogram map[string]int |
||||
maxDepth int |
||||
label string |
||||
} |
||||
|
||||
type strDynDistEntry struct { |
||||
cmdLine string |
||||
distance float64 |
||||
} |
||||
|
||||
func (s *strategyDynamicRecordDistance) init() { |
||||
s.history = nil |
||||
s.pwdHistogram = map[string]int{} |
||||
s.realPwdHistogram = map[string]int{} |
||||
} |
||||
|
||||
func (s *strategyDynamicRecordDistance) GetTitleAndDescription() (string, string) { |
||||
return "dynamic record distance (depth:" + strconv.Itoa(s.maxDepth) + ";" + s.label + ")", "Use TF-IDF record distance to recommend commands" |
||||
} |
||||
|
||||
func (s *strategyDynamicRecordDistance) idf(count int) float64 { |
||||
return math.Log(float64(len(s.history)) / float64(count)) |
||||
} |
||||
|
||||
func (s *strategyDynamicRecordDistance) GetCandidates() []string { |
||||
if len(s.history) == 0 { |
||||
return nil |
||||
} |
||||
var prevRecord common.EnrichedRecord |
||||
prevRecord = s.history[0] |
||||
prevRecord.SetCmdLine("") |
||||
prevRecord.SetBeforeToAfter() |
||||
var mapItems []strDynDistEntry |
||||
for i, record := range s.history { |
||||
if s.maxDepth != 0 && i > s.maxDepth { |
||||
break |
||||
} |
||||
distParams := common.DistParams{ |
||||
Pwd: s.distParams.Pwd * s.idf(s.pwdHistogram[prevRecord.PwdAfter]), |
||||
RealPwd: s.distParams.RealPwd * s.idf(s.realPwdHistogram[prevRecord.RealPwdAfter]), |
||||
Time: s.distParams.Time, |
||||
SessionID: s.distParams.SessionID, |
||||
} |
||||
distance := record.DistanceTo(prevRecord, distParams) |
||||
mapItems = append(mapItems, strDynDistEntry{record.CmdLine, distance}) |
||||
} |
||||
sort.SliceStable(mapItems, func(i int, j int) bool { return mapItems[i].distance < mapItems[j].distance }) |
||||
var hist []string |
||||
histSet := map[string]bool{} |
||||
for _, item := range mapItems { |
||||
if histSet[item.cmdLine] { |
||||
continue |
||||
} |
||||
histSet[item.cmdLine] = true |
||||
hist = append(hist, item.cmdLine) |
||||
} |
||||
return hist |
||||
} |
||||
|
||||
func (s *strategyDynamicRecordDistance) AddHistoryRecord(record *common.EnrichedRecord) error { |
||||
// append record to front
|
||||
s.history = append([]common.EnrichedRecord{*record}, s.history...) |
||||
s.pwdHistogram[record.Pwd]++ |
||||
s.realPwdHistogram[record.RealPwd]++ |
||||
return nil |
||||
} |
||||
|
||||
func (s *strategyDynamicRecordDistance) ResetHistory() error { |
||||
s.init() |
||||
return nil |
||||
} |
||||
Loading…
Reference in new issue