github.com/tunabay/go-bitarray@v1.3.1/bitarray_rand_test.go (about)

     1  // Copyright (c) 2021 Hirotsuna Mizuno. All rights reserved.
     2  // Use of this source code is governed by the MIT license that can be found in
     3  // the LICENSE file.
     4  
     5  package bitarray_test
     6  
     7  import (
     8  	"math/rand"
     9  	"testing"
    10  
    11  	"github.com/tunabay/go-bitarray"
    12  )
    13  
    14  func TestRand(t *testing.T) {
    15  	ba0, err := bitarray.Rand(0)
    16  	if err != nil {
    17  		t.Fatalf("unexpected error: %v", err)
    18  	}
    19  	ba0.V()
    20  	if ba0.Len() != 0 {
    21  		t.Errorf("unexpected Len: got %d, want 0", ba0.Len())
    22  		t.Logf("data: %s", ba0.D())
    23  	}
    24  	if !ba0.IsZero() {
    25  		t.Errorf("unexpected IsZero: got %t, want true", ba0.IsZero())
    26  		t.Logf("data: %s", ba0.D())
    27  	}
    28  
    29  	sizes := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 16, 17, 63, 64, 65, 257}
    30  	for _, sz := range sizes {
    31  		expUniq := 8192
    32  		if sz < 13 {
    33  			expUniq = 1 << sz
    34  		}
    35  		hist := make(map[string]int, expUniq)
    36  		for i := 0; i < 8192; i++ {
    37  			ba, err := bitarray.Rand(sz)
    38  			if err != nil {
    39  				t.Fatalf("unexpected error: %v", err)
    40  			}
    41  			ba.V()
    42  			if ba.Len() != sz {
    43  				t.Errorf("unexpected Len: got %d, want %d", ba.Len(), sz)
    44  				t.Logf("data: %s", ba.D())
    45  			}
    46  			s := ba.String()
    47  			if cnt, dup := hist[s]; dup {
    48  				hist[s] = cnt + 1
    49  			} else {
    50  				hist[s] = 1
    51  			}
    52  		}
    53  		passUniq := expUniq
    54  		switch sz {
    55  		case 15:
    56  			passUniq = 5734 // -30%
    57  		case 16:
    58  			passUniq = 6553 // -20%
    59  		case 17:
    60  			passUniq = 7373 // -10%
    61  		}
    62  		uniq := len(hist)
    63  		if uniq < passUniq {
    64  			t.Errorf(
    65  				"sz=%d: data not distributed as expected: uniq=%d, threshold=%d, ideal=%d",
    66  				sz, uniq, passUniq, expUniq,
    67  			)
    68  		} else {
    69  			// t.Logf("sz=%d: uniq=%d, threshold=%d, ideal=%d", sz, uniq, passUniq, expUniq)
    70  		}
    71  	}
    72  }
    73  
    74  func TestPseudoRand(t *testing.T) {
    75  	ba0 := bitarray.PseudoRand(0, nil)
    76  	ba0.V()
    77  	if ba0.Len() != 0 {
    78  		t.Errorf("unexpected Len: got %d, want 0", ba0.Len())
    79  		t.Logf("data: %s", ba0.D())
    80  	}
    81  	if !ba0.IsZero() {
    82  		t.Errorf("unexpected IsZero: got %t, want true", ba0.IsZero())
    83  		t.Logf("data: %s", ba0.D())
    84  	}
    85  
    86  	myRand := rand.New(rand.NewSource(1234))
    87  	sizes := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 16, 17, 63, 64, 65, 257}
    88  	for i, sz := range sizes {
    89  		randSrc := myRand
    90  		if i&1 == 0 {
    91  			randSrc = nil
    92  		}
    93  		expUniq := 8192
    94  		if sz < 13 {
    95  			expUniq = 1 << sz
    96  		}
    97  		hist := make(map[string]int, expUniq)
    98  		for i := 0; i < 8192; i++ {
    99  			ba := bitarray.PseudoRand(sz, randSrc)
   100  			ba.V()
   101  			if ba.Len() != sz {
   102  				t.Errorf("unexpected Len: got %d, want %d", ba.Len(), sz)
   103  				t.Logf("data: %s", ba.D())
   104  			}
   105  			s := ba.String()
   106  			if cnt, dup := hist[s]; dup {
   107  				hist[s] = cnt + 1
   108  			} else {
   109  				hist[s] = 1
   110  			}
   111  		}
   112  		passUniq := expUniq
   113  		switch sz {
   114  		case 15:
   115  			passUniq = 5734 // -30%
   116  		case 16:
   117  			passUniq = 6553 // -20%
   118  		case 17:
   119  			passUniq = 7373 // -10%
   120  		}
   121  		uniq := len(hist)
   122  		if uniq < passUniq {
   123  			t.Errorf(
   124  				"sz=%d: data not distributed as expected: uniq=%d, threshold=%d, ideal=%d",
   125  				sz, uniq, passUniq, expUniq,
   126  			)
   127  		} else {
   128  			// t.Logf("sz=%d: uniq=%d, threshold=%d, ideal=%d", sz, uniq, passUniq, expUniq)
   129  		}
   130  	}
   131  }