Move bisectRight implementation to internal/bisect

This commit is contained in:
c-bata 2018-12-09 16:24:01 +09:00
parent b47e013727
commit 24941a6503
5 changed files with 73 additions and 31 deletions

View File

@ -21,8 +21,12 @@ lint: ## Run golint and go vet.
@go vet .
.PHONY: test
test: ## Run the tests with race condition checking.
@go test -race .
test: ## Run tests with race condition checking.
@go test -race ./...
.PHONY: bench
bench: ## Run benchmarks.
@go test -bench=. -run=- -benchmem ./...
.PHONY: coverage
cover: ## Run the tests.

View File

@ -1,10 +1,10 @@
package prompt
import (
"sort"
"strings"
"unicode/utf8"
"github.com/c-bata/go-prompt/internal/bisect"
runewidth "github.com/mattn/go-runewidth"
)
@ -292,7 +292,7 @@ func (d *Document) lineStartIndexes() []int {
// the first character on that line.
func (d *Document) findLineStartIndex(index int) (pos int, lineStartIndex int) {
indexes := d.lineStartIndexes()
pos = bisectRight(indexes, index) - 1
pos = bisect.Right(indexes, index) - 1
lineStartIndex = indexes[pos]
return
}
@ -433,18 +433,6 @@ func (d *Document) leadingWhitespaceInCurrentLine() (margin string) {
return
}
// bisectRight to Locate the insertion point for v in a to maintain sorted order.
func bisectRight(a []int, v int) int {
return bisectRightRange(a, v, 0, len(a))
}
func bisectRightRange(a []int, v int, lo, hi int) int {
s := a[lo:hi]
return sort.Search(len(s), func(i int) bool {
return s[i] > v
})
}
func indexByteNot(s string, c byte) int {
n := len(s)
for i := 0; i < n; i++ {

View File

@ -1040,18 +1040,3 @@ func TestDocument_GetEndOfLinePosition(t *testing.T) {
t.Errorf("Should be %#v, got %#v", ex, ac)
}
}
func TestBisectRight(t *testing.T) {
// Thanks!! https://play.golang.org/p/y9NRj_XVIW
in := []int{1, 2, 3, 3, 3, 6, 7}
r := bisectRight(in, 0)
if r != 0 {
t.Errorf("number 0 should inserted at 0 position, but got %d", r)
}
r = bisectRight(in, 4)
if r != 5 {
t.Errorf("number 4 should inserted at 5 position, but got %d", r)
}
}

15
internal/bisect/bisect.go Normal file
View File

@ -0,0 +1,15 @@
package bisect
import "sort"
// Right to locate the insertion point for v in a to maintain sorted order.
func Right(a []int, v int) int {
return bisectRightRange(a, v, 0, len(a))
}
func bisectRightRange(a []int, v int, lo, hi int) int {
s := a[lo:hi]
return sort.Search(len(s), func(i int) bool {
return s[i] > v
})
}

View File

@ -0,0 +1,50 @@
package bisect_test
import (
"fmt"
"math/rand"
"testing"
"github.com/c-bata/go-prompt/internal/bisect"
)
func Example() {
in := []int{1, 2, 3, 3, 3, 6, 7}
fmt.Println("Insertion position for 0 in the slice is", bisect.Right(in, 0))
fmt.Println("Insertion position for 4 in the slice is", bisect.Right(in, 4))
// Output:
// Insertion position for 0 in the slice is 0
// Insertion position for 4 in the slice is 5
}
func TestBisectRight(t *testing.T) {
// Thanks!! https://play.golang.org/p/y9NRj_XVIW
in := []int{1, 2, 3, 3, 3, 6, 7}
r := bisect.Right(in, 0)
if r != 0 {
t.Errorf("number 0 should inserted at 0 position, but got %d", r)
}
r = bisect.Right(in, 4)
if r != 5 {
t.Errorf("number 4 should inserted at 5 position, but got %d", r)
}
}
func BenchmarkRight(b *testing.B) {
rand.Seed(0)
for _, l := range []int{10, 1e2, 1e3, 1e4} {
x := rand.Perm(l)
insertion := rand.Int()
b.Run(fmt.Sprintf("arrayLength=%d", l), func(b *testing.B) {
b.ResetTimer()
for n := 0; n < b.N; n++ {
bisect.Right(x, insertion)
}
})
}
}