featurebase/ingest/sort_test.go
Seebs 016765d8a2 Prototype ingest API
This partially-implemented prototype of the ingest API is based on our
programmatic ingest API reference. It has noticable limitations, most
crucially that it doesn't handle multi-node clusters right now. However,
it basically implements the expected semantics.

There's some noticeable performance issues to do with the high overhead
of sorting bits in order to import them efficiently, but this is fixable.

We also add the hooks to the internal client, and make the finisher logic
a bit smarter.

Much of this code was originally by Nia Weiss, but it's been merged
and restructured a bit to get things broken into logical commits.
2021-08-19 09:50:59 -05:00

184 lines
3.9 KiB
Go

// Copyright 2021 Molecula Corp.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package ingest
// func BenchmarkSort64(b *testing.B) {
// gen := func(n, width uint64) func() []uint64 {
// var data []uint64
// var once sync.Once
// return func() []uint64 {
// once.Do(func() {
// data = make([]uint64, n)
// var rng rand.PCGSource
// rng.Seed(9001)
// for i := range data {
// data[i] = rng.Uint64() % width
// }
// })
//
// return data
// }
// }
//
// algos := []struct {
// name string
// maxn uint64
// fn func([]uint64) []uint64
// }{
// {
// name: "stdlib",
// maxn: 1024 * 1024 * 1024,
// fn: stdSort,
// },
// {
// name: "heap",
// maxn: 1024 * 1024 * 1024,
// fn: heapSort,
// },
// {
// name: "radix-insertion-mask",
// maxn: 1024 * 1024 * 1024,
// fn: dedupSort64,
// },
// }
//
// widths := []struct {
// name string
// width uint64
// }{
// {"64", 64},
// {"1K", 1024},
// {"64K", 64 * 1024},
// {"1M", 1024 * 1024},
// {"16M", 16 * 1024 * 1024},
// {"128M", 128 * 1024 * 1024},
// {"1B", 1024 * 1024 * 1024},
// }
//
// counts := []struct {
// name string
// n uint64
// }{
// {"64", 64},
// {"1K", 1024},
// {"64K", 64 * 1024},
// {"1M", 1024 * 1024},
// {"4M", 4 * 1024 * 1024},
// {"16M", 16 * 1024 * 1024},
// {"64M", 64 * 1024 * 1024},
// {"256M", 256 * 1024 * 1024},
// }
//
// for _, width := range widths {
// width := width
// b.Run(width.name, func(b *testing.B) {
// for _, count := range counts {
// if count.n > width.width {
// continue
// }
//
// count := count
// b.Run(count.name, func(b *testing.B) {
// datasrc := gen(count.n, width.width)
// for _, alg := range algos {
// if count.n > alg.maxn {
// continue
// }
//
// alg := alg
// b.Run(alg.name, func(b *testing.B) {
// data := datasrc()
// buf := make([]uint64, len(data))
// b.SetBytes(8 * int64(len(buf)))
//
// b.StopTimer()
// b.ResetTimer()
//
// for i := 0; i < b.N; i++ {
// copy(buf, data)
// b.StartTimer()
// alg.fn(buf)
// b.StopTimer()
// }
// })
// }
// })
// }
// })
// }
// }
//
// func heapSort(data []uint64) []uint64 {
// for i, v := range data {
// for i > 0 && v > data[(i-1)/2] {
// data[i] = data[(i-1)/2]
// i = (i - 1) / 2
// }
// data[i] = v
// }
// {
// heap := data
// for len(heap) > 1 {
// heap[0], heap[len(heap)-1] = heap[len(heap)-1], heap[0]
// heap = heap[:len(heap)-1]
// i := 0
// for {
// max := i
// if r := 2*i + 1; r < len(heap) && heap[r] > heap[max] {
// max = r
// }
// if l := 2*i + 2; l < len(heap) && heap[l] > heap[max] {
// max = l
// }
// if max == i {
// break
// }
//
// heap[max], heap[i] = heap[i], heap[max]
// i = max
// }
// }
// }
//
// j := 1
// prev := data[0]
// for _, v := range data[1:] {
// if v == prev {
// continue
// }
//
// data[j] = v
// prev = v
// }
//
// return data[:j]
// }
//
// func stdSort(data []uint64) []uint64 {
// sort.Slice(data, func(i, j int) bool { return data[i] < data[j] })
//
// j := 1
// prev := data[0]
// for _, v := range data[1:] {
// if v == prev {
// continue
// }
//
// data[j] = v
// prev = v
// }
//
// return data[:j]
// }