Newer
Older
/*
* Copyright 2016 Dgraph Labs, Inc.
*
* 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 algo
import (
"github.com/dgraph-io/dgraph/task"
"github.com/stretchr/testify/require"
func newList(data []uint64) *task.List {
return SortedListToBlock(data)
func TestSort1(t *testing.T) {
input := newList([]uint64{55})
Sort(input)
require.Equal(t, BlockToList(input), []uint64{55})
}
func TestSort2(t *testing.T) {
input := newList([]uint64{})
Sort(input)
require.Equal(t, BlockToList(input), []uint64{})
}
func TestSort3(t *testing.T) {
input := newList([]uint64{55, 392, 1, 123})
Sort(input)
require.Equal(t, BlockToList(input), []uint64{1, 55, 123, 392})
}
func TestSort4(t *testing.T) {
input := newList([]uint64{55, 1, 100000})
Sort(input)
require.Equal(t, BlockToList(input), []uint64{1, 55, 100000})
}
input := []*task.List{
newList([]uint64{55}),
require.Equal(t, BlockToList(MergeSorted(input)), []uint64{55})
input := []*task.List{
newList([]uint64{1, 3, 6, 8, 10}),
newList([]uint64{2, 4, 5, 7, 15}),
require.Equal(t, BlockToList(MergeSorted(input)),
input := []*task.List{
newList([]uint64{1, 3, 6, 8, 10}),
newList([]uint64{}),
require.Equal(t, BlockToList(MergeSorted(input)), []uint64{1, 3, 6, 8, 10})
input := []*task.List{
newList([]uint64{}),
newList([]uint64{1, 3, 6, 8, 10}),
require.Equal(t, BlockToList(MergeSorted(input)), []uint64{1, 3, 6, 8, 10})
input := []*task.List{
newList([]uint64{}),
newList([]uint64{}),
require.Empty(t, BlockToList(MergeSorted(input)))
input := []*task.List{
newList([]uint64{11, 13, 16, 18, 20}),
newList([]uint64{12, 14, 15, 15, 16, 16, 17, 25}),
newList([]uint64{1, 2}),
require.Equal(t, BlockToList(MergeSorted(input)),
input := []*task.List{
newList([]uint64{5, 6, 7}),
newList([]uint64{3, 4}),
newList([]uint64{1, 2}),
newList([]uint64{}),
require.Equal(t, BlockToList(MergeSorted(input)), []uint64{1, 2, 3, 4, 5, 6, 7})
require.Empty(t, BlockToList(MergeSorted(input)))
input := []*task.List{
newList([]uint64{1, 1, 1}),
require.Equal(t, BlockToList(MergeSorted(input)), []uint64{1})
input := []*task.List{
newList([]uint64{1, 2, 3, 3, 6}),
newList([]uint64{4, 8, 9}),
require.Equal(t, BlockToList(MergeSorted(input)), []uint64{1, 2, 3, 4, 6, 8, 9})
input := []*task.List{
newList([]uint64{1, 2, 3}),
newList([]uint64{2, 3, 4, 5}),
require.Equal(t, BlockToList(IntersectSorted(input)), []uint64{2, 3})
input := []*task.List{
newList([]uint64{1, 2, 3}),
require.Equal(t, BlockToList(IntersectSorted(input)), []uint64{1, 2, 3})
require.Empty(t, BlockToList(IntersectSorted(input)))
input := []*task.List{
newList([]uint64{100, 101}),
require.Equal(t, BlockToList(IntersectSorted(input)), []uint64{100, 101})
input := []*task.List{
newList([]uint64{1, 2, 3}),
newList([]uint64{2, 3, 4, 5}),
newList([]uint64{4, 5, 6}),
require.Empty(t, BlockToList(IntersectSorted(input)))
func TestIntersectSorted6(t *testing.T) {
input := []*task.List{
newList([]uint64{10, 12, 13}),
newList([]uint64{2, 3, 4, 13}),
newList([]uint64{4, 5, 6}),
}
require.Empty(t, BlockToList(IntersectSorted(input)))
func TestSubSorted1(t *testing.T) {
input := []*task.List{
newList([]uint64{1, 2, 3}),
newList([]uint64{2, 3, 4, 5}),
}
Difference(input[0], input[1])
require.Equal(t, []uint64{1}, BlockToList(input[0]))
}
func TestSubSorted6(t *testing.T) {
input := []*task.List{
newList([]uint64{10, 12, 13}),
newList([]uint64{2, 3, 4, 13}),
}
Difference(input[0], input[1])
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
require.Equal(t, []uint64{10, 12}, BlockToList(input[0]))
}
func TestIterator1(t *testing.T) {
u := newList([]uint64{1, 2, 3, 4, 43, 234, 2344})
it := NewListIterator(u)
var res []uint64
for ; it.Valid(); it.Next() {
res = append(res, it.Val())
}
require.Equal(t, []uint64{1, 2, 3, 4, 43, 234, 2344}, res)
}
func TestIterator2(t *testing.T) {
var ls, res []uint64
for i := 0; i < 1000; i++ {
ls = append(ls, uint64(i*2))
}
u := newList(ls)
it := NewListIterator(u)
for ; it.Valid(); it.Next() {
res = append(res, it.Val())
}
require.Equal(t, ls, res)
}
u := newList([]uint64{1, 2, 3})
v := newList([]uint64{})
IntersectWith(u, v)
require.Empty(t, BlockToList(u))
u := newList([]uint64{1, 2, 3})
v := newList([]uint64{1, 2, 3, 4, 5})
IntersectWith(u, v)
require.Equal(t, []uint64{1, 2, 3}, BlockToList(u))
u := newList([]uint64{1, 2, 3})
v := newList([]uint64{2})
IntersectWith(u, v)
require.Equal(t, []uint64{2}, BlockToList(u))
u := newList([]uint64{1, 2, 3})
v := newList([]uint64{0, 5})
IntersectWith(u, v)
require.Empty(t, BlockToList(u))
u := newList([]uint64{1, 2, 3})
v := newList([]uint64{3, 5})
IntersectWith(u, v)
require.Equal(t, []uint64{3}, BlockToList(u))
func TestUIDListIntersectDupFirst(t *testing.T) {
u := newList([]uint64{1, 1, 2, 3})
v := newList([]uint64{1, 2})
IntersectWith(u, v)
require.Equal(t, []uint64{1, 2}, BlockToList(u))
}
func TestUIDListIntersectDupBoth(t *testing.T) {
u := newList([]uint64{1, 1, 2, 3, 5})
v := newList([]uint64{1, 1, 2, 4})
IntersectWith(u, v)
require.Equal(t, []uint64{1, 1, 2}, BlockToList(u))
}
func TestUIDListIntersectDupSecond(t *testing.T) {
u := newList([]uint64{1, 2, 3, 5})
v := newList([]uint64{1, 1, 2, 4})
IntersectWith(u, v)
require.Equal(t, []uint64{1, 2}, BlockToList(u))
l := []uint64{1, 2, 3, 4, 5}
u := newList(l)
ApplyFilter(u, func(a uint64, idx int) bool { return (l[idx] % 2) == 1 })
require.Equal(t, []uint64{1, 3, 5}, BlockToList(u))
// sort interface for []uint64
type uint64Slice []uint64
func (xs uint64Slice) Len() int {
return len(xs)
}
func (xs uint64Slice) Less(i, j int) bool {
return xs[i] < xs[j]
}
func (xs uint64Slice) Swap(i, j int) {
xs[i], xs[j] = xs[j], xs[i]
}
func TestWriteListLen(t *testing.T) {
var u task.List
w := NewWriteIterator(&u)
n := blockSize*5 + 10
for i := 0; i < n; i++ {
w.Append(uint64(i))
require.EqualValues(t, i+1, w.ListLen())
}
w.End()
require.EqualValues(t, n, ListLen(&u))
}
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
// Benchmarks for IntersectWith
// random data : u and v having data within range [0, limit)
// where limit = N * sizeof-list ; for different N
func runIntersectRandom(arrSz int, limit int64, b *testing.B) {
u1, v1 := make([]uint64, arrSz, arrSz), make([]uint64, arrSz, arrSz)
for i := 0; i < arrSz; i++ {
u1[i] = uint64(rand.Int63n(limit))
v1[i] = uint64(rand.Int63n(limit))
}
sort.Sort(uint64Slice(u1))
sort.Sort(uint64Slice(v1))
u := newList(u1)
v := newList(v1)
ucopy := make([]uint64, len(u1), len(u1))
copy(ucopy, u1)
b.ResetTimer()
for k := 0; k < b.N; k++ {
IntersectWith(u, v)
u.Uids = u.Uids[:arrSz]
copy(u.Uids, ucopy)
}
}
func BenchmarkListIntersectRandom(b *testing.B) {
randomTests := func(sz int, overlap float64) {
b.Run(fmt.Sprintf(":random:size=%d:overlap=%.2f:", sz, overlap),
func(b *testing.B) {
runIntersectRandom(sz, int64(float64(sz)/overlap), b)
})
}
randomTests(500, 0.3)
randomTests(10000, 0.3)
randomTests(1000000, 0.3)
randomTests(500, 0.1)
randomTests(10000, 0.1)
randomTests(1000000, 0.1)
randomTests(500, 0.01)
randomTests(10000, 0.01)
randomTests(1000000, 0.01)
}