core/filtermaps: simplified matcher

This commit is contained in:
Zsolt Felfoldi 2025-03-14 10:13:38 +01:00
parent 8b3aa452cf
commit 8f2f37da67

View file

@ -550,24 +550,18 @@ type matchSequence struct {
// newInstance creates a new instance of matchSequence. // newInstance creates a new instance of matchSequence.
func (m *matchSequence) newInstance(mapIndices []uint32) matcherInstance { func (m *matchSequence) newInstance(mapIndices []uint32) matcherInstance {
// determine set of indices to request from next matcher // determine set of indices to request from next matcher
nextIndices := make([]uint32, 0, len(mapIndices)*3/2)
needMatched := make(map[uint32]struct{}) needMatched := make(map[uint32]struct{})
baseRequested := make(map[uint32]struct{}) baseRequested := make(map[uint32]struct{})
nextRequested := make(map[uint32]struct{}) nextRequested := make(map[uint32]struct{})
for _, mapIndex := range mapIndices { for _, mapIndex := range mapIndices {
needMatched[mapIndex] = struct{}{} needMatched[mapIndex] = struct{}{}
baseRequested[mapIndex] = struct{}{} baseRequested[mapIndex] = struct{}{}
if _, ok := nextRequested[mapIndex]; !ok { nextRequested[mapIndex] = struct{}{}
nextIndices = append(nextIndices, mapIndex)
nextRequested[mapIndex] = struct{}{}
}
nextIndices = append(nextIndices, mapIndex+1)
nextRequested[mapIndex+1] = struct{}{}
} }
return &matchSequenceInstance{ return &matchSequenceInstance{
matchSequence: m, matchSequence: m,
baseInstance: m.base.newInstance(mapIndices), baseInstance: m.base.newInstance(mapIndices),
nextInstance: m.next.newInstance(nextIndices), nextInstance: m.next.newInstance(mapIndices),
needMatched: needMatched, needMatched: needMatched,
baseRequested: baseRequested, baseRequested: baseRequested,
nextRequested: nextRequested, nextRequested: nextRequested,
@ -687,12 +681,9 @@ func (m *matchSequenceInstance) getMatchesForLayer(ctx context.Context, layerInd
if _, ok := m.nextRequested[mapIndex]; ok { if _, ok := m.nextRequested[mapIndex]; ok {
continue continue
} }
if _, ok := m.nextRequested[mapIndex+1]; ok {
continue
}
matchedResults = append(matchedResults, matcherResult{ matchedResults = append(matchedResults, matcherResult{
mapIndex: mapIndex, mapIndex: mapIndex,
matches: m.params.matchResults(mapIndex, m.offset, m.baseResults[mapIndex], m.nextResults[mapIndex], m.nextResults[mapIndex+1]), matches: m.params.matchResults(mapIndex, m.offset, m.baseResults[mapIndex], m.nextResults[mapIndex]),
}) })
delete(m.needMatched, mapIndex) delete(m.needMatched, mapIndex)
} }
@ -715,9 +706,6 @@ func (m *matchSequenceInstance) dropIndices(dropIndices []uint32) {
if m.dropNext(mapIndex) { if m.dropNext(mapIndex) {
dropNext = append(dropNext, mapIndex) dropNext = append(dropNext, mapIndex)
} }
if m.dropNext(mapIndex + 1) {
dropNext = append(dropNext, mapIndex+1)
}
} }
m.nextInstance.dropIndices(dropNext) m.nextInstance.dropIndices(dropNext)
} }
@ -743,9 +731,6 @@ func (m *matchSequenceInstance) evalBase(ctx context.Context, layerIndex uint32)
if m.dropNext(r.mapIndex) { if m.dropNext(r.mapIndex) {
dropIndices = append(dropIndices, r.mapIndex) dropIndices = append(dropIndices, r.mapIndex)
} }
if m.dropNext(r.mapIndex + 1) {
dropIndices = append(dropIndices, r.mapIndex+1)
}
} }
if len(dropIndices) > 0 { if len(dropIndices) > 0 {
m.nextInstance.dropIndices(dropIndices) m.nextInstance.dropIndices(dropIndices)
@ -771,9 +756,6 @@ func (m *matchSequenceInstance) evalNext(ctx context.Context, layerIndex uint32)
} }
m.mergeNextStats(stats) m.mergeNextStats(stats)
for _, r := range results { for _, r := range results {
if r.mapIndex > 0 && m.dropBase(r.mapIndex-1) {
dropIndices = append(dropIndices, r.mapIndex-1)
}
if m.dropBase(r.mapIndex) { if m.dropBase(r.mapIndex) {
dropIndices = append(dropIndices, r.mapIndex) dropIndices = append(dropIndices, r.mapIndex)
} }
@ -792,12 +774,7 @@ func (m *matchSequenceInstance) dropBase(mapIndex uint32) bool {
return false return false
} }
if _, ok := m.needMatched[mapIndex]; ok { if _, ok := m.needMatched[mapIndex]; ok {
if next := m.nextResults[mapIndex]; next == nil || if next := m.nextResults[mapIndex]; next == nil || len(next) > 0 {
(len(next) > 0 && next[len(next)-1] >= (uint64(mapIndex)<<m.params.logValuesPerMap)+m.offset) {
return false
}
if nextNext := m.nextResults[mapIndex+1]; nextNext == nil ||
(len(nextNext) > 0 && nextNext[0] < (uint64(mapIndex+1)<<m.params.logValuesPerMap)+m.offset) {
return false return false
} }
} }
@ -812,15 +789,8 @@ func (m *matchSequenceInstance) dropNext(mapIndex uint32) bool {
if _, ok := m.nextRequested[mapIndex]; !ok { if _, ok := m.nextRequested[mapIndex]; !ok {
return false return false
} }
if _, ok := m.needMatched[mapIndex-1]; ok {
if prevBase := m.baseResults[mapIndex-1]; prevBase == nil ||
(len(prevBase) > 0 && prevBase[len(prevBase)-1]+m.offset >= (uint64(mapIndex)<<m.params.logValuesPerMap)) {
return false
}
}
if _, ok := m.needMatched[mapIndex]; ok { if _, ok := m.needMatched[mapIndex]; ok {
if base := m.baseResults[mapIndex]; base == nil || if base := m.baseResults[mapIndex]; base == nil || len(base) > 0 {
(len(base) > 0 && base[0]+m.offset < (uint64(mapIndex+1)<<m.params.logValuesPerMap)) {
return false return false
} }
} }
@ -833,59 +803,39 @@ func (m *matchSequenceInstance) dropNext(mapIndex uint32) bool {
// results at mapIndex and mapIndex+1. Note that acquiring nextNextRes may be // results at mapIndex and mapIndex+1. Note that acquiring nextNextRes may be
// skipped and it can be substituted with an empty list if baseRes has no potential // skipped and it can be substituted with an empty list if baseRes has no potential
// matches that could be sequence matched with anything that could be in nextNextRes. // matches that could be sequence matched with anything that could be in nextNextRes.
func (params *Params) matchResults(mapIndex uint32, offset uint64, baseRes, nextRes, nextNextRes potentialMatches) potentialMatches { func (params *Params) matchResults(mapIndex uint32, offset uint64, baseRes, nextRes potentialMatches) potentialMatches {
if nextRes == nil || (baseRes != nil && len(baseRes) == 0) { if nextRes == nil || (baseRes != nil && len(baseRes) == 0) {
// if nextRes is a wild card or baseRes is empty then the sequence matcher // if nextRes is a wild card or baseRes is empty then the sequence matcher
// result equals baseRes. // result equals baseRes.
return baseRes return baseRes
} }
if len(nextRes) > 0 { if baseRes == nil || (nextRes != nil && len(nextRes) == 0) {
// discard items from nextRes whose corresponding base matcher results // if baseRes is a wild card or nextRes is empty then the sequence matcher
// with the negative offset applied would be located at mapIndex-1. // result is the items of nextRes with a negative offset applied.
start := 0 result := make(potentialMatches, 0, len(nextRes))
for start < len(nextRes) && nextRes[start] < uint64(mapIndex)<<params.logValuesPerMap+offset { min := (uint64(mapIndex) << params.logValuesPerMap) + offset
start++ for _, v := range nextRes {
if v >= min {
result = append(result, v-offset)
}
} }
nextRes = nextRes[start:] return result
} }
if len(nextNextRes) > 0 { // iterate through baseRes and nextRes in parallel and collect matching results.
// discard items from nextNextRes whose corresponding base matcher results maxLen := len(baseRes)
// with the negative offset applied would still be located at mapIndex+1. if l := len(nextRes); l < maxLen {
stop := 0 maxLen = l
for stop < len(nextNextRes) && nextNextRes[stop] < uint64(mapIndex+1)<<params.logValuesPerMap+offset {
stop++
}
nextNextRes = nextNextRes[:stop]
} }
maxLen := len(nextRes) + len(nextNextRes)
if maxLen == 0 {
return nextRes
}
if len(baseRes) < maxLen {
maxLen = len(baseRes)
}
// iterate through baseRes, nextRes and nextNextRes and collect matching results.
matchedRes := make(potentialMatches, 0, maxLen) matchedRes := make(potentialMatches, 0, maxLen)
for _, nextRes := range []potentialMatches{nextRes, nextNextRes} { for len(nextRes) > 0 && len(baseRes) > 0 {
if baseRes != nil { if nextRes[0] > baseRes[0]+offset {
for len(nextRes) > 0 && len(baseRes) > 0 { baseRes = baseRes[1:]
if nextRes[0] > baseRes[0]+offset { } else if nextRes[0] < baseRes[0]+offset {
baseRes = baseRes[1:] nextRes = nextRes[1:]
} else if nextRes[0] < baseRes[0]+offset {
nextRes = nextRes[1:]
} else {
matchedRes = append(matchedRes, baseRes[0])
baseRes = baseRes[1:]
nextRes = nextRes[1:]
}
}
} else { } else {
// baseRes is a wild card so just return next matcher results with matchedRes = append(matchedRes, baseRes[0])
// negative offset. baseRes = baseRes[1:]
for len(nextRes) > 0 { nextRes = nextRes[1:]
matchedRes = append(matchedRes, nextRes[0]-offset)
nextRes = nextRes[1:]
}
} }
} }
return matchedRes return matchedRes