github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/soliton/bitmap/concurrent_test.go (about)

     1  // Copyright 2020 WHTCORPS INC, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package bitmap
    15  
    16  import (
    17  	"sync"
    18  	"sync/atomic"
    19  	"testing"
    20  
    21  	. "github.com/whtcorpsinc/check"
    22  )
    23  
    24  func TestT(t *testing.T) {
    25  	TestingT(t)
    26  }
    27  
    28  var _ = Suite(&testBitmap{})
    29  
    30  type testBitmap struct{}
    31  
    32  func (s *testBitmap) TestConcurrentBitmapSet(c *C) {
    33  	const loopCount = 1000
    34  	const interval = 2
    35  
    36  	bm := NewConcurrentBitmap(loopCount * interval)
    37  	wg := &sync.WaitGroup{}
    38  	for i := 0; i < loopCount; i++ {
    39  		wg.Add(1)
    40  		go func(bitIndex int) {
    41  			bm.Set(bitIndex)
    42  			wg.Done()
    43  		}(i * interval)
    44  	}
    45  	wg.Wait()
    46  
    47  	for i := 0; i < loopCount; i++ {
    48  		if i%interval == 0 {
    49  			c.Assert(bm.UnsafeIsSet(i), IsTrue)
    50  		} else {
    51  			c.Assert(bm.UnsafeIsSet(i), IsFalse)
    52  		}
    53  	}
    54  }
    55  
    56  // TestConcurrentBitmapUniqueSetter checks if isSetter is unique everytime
    57  // when a bit is set.
    58  func (s *testBitmap) TestConcurrentBitmapUniqueSetter(c *C) {
    59  	const loopCount = 10000
    60  	const competitorsPerSet = 50
    61  
    62  	wg := &sync.WaitGroup{}
    63  	bm := NewConcurrentBitmap(32)
    64  	var setterCounter uint64
    65  	var clearCounter uint64
    66  	// Concurrently set bit, and check if isSetter count matchs zero clearing count.
    67  	for i := 0; i < loopCount; i++ {
    68  		// Clear bitmap to zero.
    69  		if atomic.CompareAndSwapUint32(&(bm.segments[0]), 0x00000001, 0x00000000) {
    70  			atomic.AddUint64(&clearCounter, 1)
    71  		}
    72  		// Concurrently set.
    73  		for j := 0; j < competitorsPerSet; j++ {
    74  			wg.Add(1)
    75  			go func() {
    76  				if bm.Set(31) {
    77  					atomic.AddUint64(&setterCounter, 1)
    78  				}
    79  				wg.Done()
    80  			}()
    81  		}
    82  	}
    83  	wg.Wait()
    84  	// If clearCounter is too big, it means setter concurrency of this test is not enough.
    85  	c.Assert(clearCounter < loopCount, Equals, true)
    86  	c.Assert(setterCounter, Equals, clearCounter+1)
    87  }