]> git.proxmox.com Git - ceph.git/blame - ceph/src/arrow/go/parquet/internal/utils/bit_block_counter_test.go
import quincy 17.2.0
[ceph.git] / ceph / src / arrow / go / parquet / internal / utils / bit_block_counter_test.go
CommitLineData
1d09f67e
TL
1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17package utils_test
18
19import (
20 "testing"
21
22 "github.com/apache/arrow/go/v6/arrow/bitutil"
23 "github.com/apache/arrow/go/v6/arrow/memory"
24 "github.com/apache/arrow/go/v6/parquet/internal/utils"
25 "github.com/stretchr/testify/assert"
26 "golang.org/x/exp/rand"
27)
28
29const kWordSize = 64
30
31func create(nbytes, offset, length int64) (*memory.Buffer, *utils.BitBlockCounter) {
32 buf := memory.NewResizableBuffer(memory.DefaultAllocator)
33 buf.Resize(int(nbytes))
34 return buf, utils.NewBitBlockCounter(buf.Bytes(), offset, length)
35}
36
37func TestOneWordBasics(t *testing.T) {
38 const nbytes = 1024
39
40 buf, counter := create(nbytes, 0, nbytes*8)
41 defer buf.Release()
42
43 var bitsScanned int64
44 for i := 0; i < nbytes/8; i++ {
45 block := counter.NextWord()
46 assert.EqualValues(t, kWordSize, block.Len)
47 assert.EqualValues(t, 0, block.Popcnt)
48 bitsScanned += int64(block.Len)
49 }
50 assert.EqualValues(t, 1024*8, bitsScanned)
51
52 block := counter.NextWord()
53 assert.Zero(t, block.Len)
54 assert.Zero(t, block.Popcnt)
55 assert.True(t, block.NoneSet())
56}
57
58func TestFourWordsBasics(t *testing.T) {
59 const nbytes = 1024
60
61 buf, counter := create(nbytes, 0, nbytes*8)
62 defer buf.Release()
63
64 var bitsScanned int64
65 for i := 0; i < nbytes/32; i++ {
66 block := counter.NextFourWords()
67 assert.EqualValues(t, 4*kWordSize, block.Len)
68 assert.EqualValues(t, 0, block.Popcnt)
69 bitsScanned += int64(block.Len)
70 }
71 assert.EqualValues(t, 1024*8, bitsScanned)
72
73 block := counter.NextFourWords()
74 assert.Zero(t, block.Len)
75 assert.Zero(t, block.Popcnt)
76}
77
78func TestOneWordWithOffsets(t *testing.T) {
79 checkWithOffset := func(offset int64) {
80 const (
81 nwords int64 = 4
82 totalBytes = nwords*8 + 1
83 )
84
85 // Trim a bit from the end of the bitmap so we can check
86 // the remainder bits behavior
87 buf, counter := create(totalBytes, offset, nwords*kWordSize-offset-1)
88 defer buf.Release()
89
90 memory.Set(buf.Bytes(), byte(0xFF))
91
92 block := counter.NextWord()
93 assert.EqualValues(t, kWordSize, block.Len)
94 assert.EqualValues(t, 64, block.Popcnt)
95
96 // add a false value to the next word
97 bitutil.SetBitTo(buf.Bytes(), kWordSize+int(offset), false)
98 block = counter.NextWord()
99 assert.EqualValues(t, 64, block.Len)
100 assert.EqualValues(t, 63, block.Popcnt)
101
102 // Set the next word to all false
103 bitutil.SetBitsTo(buf.Bytes(), 2*kWordSize+offset, kWordSize, false)
104
105 block = counter.NextWord()
106 assert.EqualValues(t, 64, block.Len)
107 assert.Zero(t, block.Popcnt)
108
109 block = counter.NextWord()
110 assert.EqualValues(t, kWordSize-offset-1, block.Len)
111 assert.EqualValues(t, block.Len, block.Popcnt)
112 assert.True(t, block.AllSet())
113
114 // we can keep calling nextword safely
115 block = counter.NextWord()
116 assert.Zero(t, block.Len)
117 assert.Zero(t, block.Popcnt)
118 }
119
120 for offsetI := int64(0); offsetI < 8; offsetI++ {
121 checkWithOffset(offsetI)
122 }
123}
124
125func TestFourWordsWithOffsets(t *testing.T) {
126 checkWithOffset := func(offset int64) {
127 const (
128 nwords = 17
129 totalBytes = nwords*8 + 1
130 )
131
132 // trim a bit from the end of the bitmap so we can check the remainder
133 // bits behavior
134 buf, counter := create(totalBytes, offset, nwords*kWordSize-offset-1)
135
136 // start with all set
137 memory.Set(buf.Bytes(), 0xFF)
138
139 block := counter.NextFourWords()
140 assert.EqualValues(t, 4*kWordSize, block.Len)
141 assert.EqualValues(t, block.Len, block.Popcnt)
142
143 // add some false values to the next 3 shifted words
144 bitutil.ClearBit(buf.Bytes(), int(4*kWordSize+offset))
145 bitutil.ClearBit(buf.Bytes(), int(5*kWordSize+offset))
146 bitutil.ClearBit(buf.Bytes(), int(6*kWordSize+offset))
147
148 block = counter.NextFourWords()
149 assert.EqualValues(t, 4*kWordSize, block.Len)
150 assert.EqualValues(t, 253, block.Popcnt)
151
152 // set the next two words to all false
153 bitutil.SetBitsTo(buf.Bytes(), 8*kWordSize+offset, 2*kWordSize, false)
154
155 // block is half set
156 block = counter.NextFourWords()
157 assert.EqualValues(t, 4*kWordSize, block.Len)
158 assert.EqualValues(t, 128, block.Popcnt)
159
160 // last full block whether offset or no
161 block = counter.NextFourWords()
162 assert.EqualValues(t, 4*kWordSize, block.Len)
163 assert.EqualValues(t, block.Len, block.Popcnt)
164
165 // partial block
166 block = counter.NextFourWords()
167 assert.EqualValues(t, kWordSize-offset-1, block.Len)
168 assert.EqualValues(t, block.Len, block.Popcnt)
169
170 // we can keep calling NextFourWords safely
171 block = counter.NextFourWords()
172 assert.Zero(t, block.Len)
173 assert.Zero(t, block.Popcnt)
174 }
175
176 for offsetI := int64(0); offsetI < 8; offsetI++ {
177 checkWithOffset(offsetI)
178 }
179}
180
181func TestFourWordsRandomData(t *testing.T) {
182 const (
183 nbytes = 1024
184 )
185
186 buf := make([]byte, nbytes)
187 r := rand.New(rand.NewSource(0))
188 r.Read(buf)
189
190 checkWithOffset := func(offset int64) {
191 counter := utils.NewBitBlockCounter(buf, offset, nbytes*8-offset)
192 for i := 0; i < nbytes/32; i++ {
193 block := counter.NextFourWords()
194 assert.EqualValues(t, bitutil.CountSetBits(buf, i*256+int(offset), int(block.Len)), block.Popcnt)
195 }
196 }
197
198 for offsetI := int64(0); offsetI < 8; offsetI++ {
199 checkWithOffset(offsetI)
200 }
201}