Use binary search in GetParaFromTextBufIndex

This commit is contained in:
bloeys
2022-08-01 07:14:35 +04:00
parent 7bb7e25e0d
commit e388e16e71
2 changed files with 29 additions and 16 deletions

30
main.go
View File

@ -1096,13 +1096,10 @@ func GetParaFromTextBufIndex(it ring.Iterator[byte], paraIt ring.Iterator[Para],
return return
} }
ticks := 0 // Find first valid para
//Find first valid para
paraIt.GotoStart() paraIt.GotoStart()
for p, done := paraIt.NextPtr(); !done; p, done = paraIt.NextPtr() { for p, done := paraIt.NextPtr(); !done; p, done = paraIt.NextPtr() {
ticks++
if !IsParaValid(it.Buf, p) { if !IsParaValid(it.Buf, p) {
continue continue
} }
@ -1111,25 +1108,30 @@ func GetParaFromTextBufIndex(it ring.Iterator[byte], paraIt ring.Iterator[Para],
break break
} }
// @PERF We need a faster way of finding the current paragraph. Binary search? // Binary search for the paragraph
for p, done := paraIt.NextPtr(); !done; p, done = paraIt.NextPtr() { lowIndexRel := paraIt.CurrToRelIndex()
highIndexRel := uint64(paraIt.Buf.Len)
for lowIndexRel <= highIndexRel {
medianIndexRel := (lowIndexRel + highIndexRel) / 2
p := paraIt.Buf.GetPtr(medianIndexRel)
ticks++
startIndexRel := it.Buf.RelIndexFromWriteCount(p.StartIndex_WriteCount) startIndexRel := it.Buf.RelIndexFromWriteCount(p.StartIndex_WriteCount)
endIndexRel := it.Buf.RelIndexFromWriteCount(p.EndIndex_WriteCount) endIndexRel := it.Buf.RelIndexFromWriteCount(p.EndIndex_WriteCount)
if textBufStartIndexRel < startIndexRel || textBufStartIndexRel > endIndexRel {
continue
}
if textBufStartIndexRel < startIndexRel {
highIndexRel = medianIndexRel - 1
} else if textBufStartIndexRel > endIndexRel {
lowIndexRel = medianIndexRel + 1
} else {
outPara = p outPara = p
pIndex = paraIt.CurrToRelIndex() pIndex = medianIndexRel
break break
} }
}
println("Ticks to finding para:", ticks)
if outPara == nil { if outPara == nil {
panic("Could not find para") panic(fmt.Sprintf("Could not find paragraph for index %d", textBufStartIndexRel))
} }
return outPara, pIndex return outPara, pIndex

View File

@ -74,6 +74,17 @@ func (b *Buffer[T]) Get(index uint64) (val T) {
return b.Data[(b.Start+int64(index))%b.Cap] return b.Data[(b.Start+int64(index))%b.Cap]
} }
// Get returns the element at the index relative from Buffer.Start
// If there are no elements then the default value of T is returned
func (b *Buffer[T]) GetPtr(index uint64) (val *T) {
if index >= uint64(b.Len) {
return new(T)
}
return &b.Data[(b.Start+int64(index))%b.Cap]
}
// AbsIndexFromRel takes an index relative to Buffer.Start and returns an absolute index into Buffer.Data // AbsIndexFromRel takes an index relative to Buffer.Start and returns an absolute index into Buffer.Data
func (b *Buffer[T]) AbsIndexFromRel(relIndex uint64) uint64 { func (b *Buffer[T]) AbsIndexFromRel(relIndex uint64) uint64 {
return uint64((b.Start + int64(relIndex)) % b.Cap) return uint64((b.Start + int64(relIndex)) % b.Cap)