github.com/ebakus/go-ebakus@v1.0.5-0.20200520105415-dbccef9ec421/common/bitutil/bitutil_test.go (about)

     1  // Copyright 2017 The go-ebakus Authors
     2  // This file is part of the go-ebakus library.
     3  //
     4  // The go-ebakus library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ebakus library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ebakus library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  // Adapted from: https://golang.org/src/crypto/cipher/xor_test.go
    18  
    19  package bitutil
    20  
    21  import (
    22  	"bytes"
    23  	"testing"
    24  )
    25  
    26  // Tests that bitwise XOR works for various alignments.
    27  func TestXOR(t *testing.T) {
    28  	for alignP := 0; alignP < 2; alignP++ {
    29  		for alignQ := 0; alignQ < 2; alignQ++ {
    30  			for alignD := 0; alignD < 2; alignD++ {
    31  				p := make([]byte, 1023)[alignP:]
    32  				q := make([]byte, 1023)[alignQ:]
    33  
    34  				for i := 0; i < len(p); i++ {
    35  					p[i] = byte(i)
    36  				}
    37  				for i := 0; i < len(q); i++ {
    38  					q[i] = byte(len(q) - i)
    39  				}
    40  				d1 := make([]byte, 1023+alignD)[alignD:]
    41  				d2 := make([]byte, 1023+alignD)[alignD:]
    42  
    43  				XORBytes(d1, p, q)
    44  				safeXORBytes(d2, p, q)
    45  				if !bytes.Equal(d1, d2) {
    46  					t.Error("not equal", d1, d2)
    47  				}
    48  			}
    49  		}
    50  	}
    51  }
    52  
    53  // Tests that bitwise AND works for various alignments.
    54  func TestAND(t *testing.T) {
    55  	for alignP := 0; alignP < 2; alignP++ {
    56  		for alignQ := 0; alignQ < 2; alignQ++ {
    57  			for alignD := 0; alignD < 2; alignD++ {
    58  				p := make([]byte, 1023)[alignP:]
    59  				q := make([]byte, 1023)[alignQ:]
    60  
    61  				for i := 0; i < len(p); i++ {
    62  					p[i] = byte(i)
    63  				}
    64  				for i := 0; i < len(q); i++ {
    65  					q[i] = byte(len(q) - i)
    66  				}
    67  				d1 := make([]byte, 1023+alignD)[alignD:]
    68  				d2 := make([]byte, 1023+alignD)[alignD:]
    69  
    70  				ANDBytes(d1, p, q)
    71  				safeANDBytes(d2, p, q)
    72  				if !bytes.Equal(d1, d2) {
    73  					t.Error("not equal")
    74  				}
    75  			}
    76  		}
    77  	}
    78  }
    79  
    80  // Tests that bitwise OR works for various alignments.
    81  func TestOR(t *testing.T) {
    82  	for alignP := 0; alignP < 2; alignP++ {
    83  		for alignQ := 0; alignQ < 2; alignQ++ {
    84  			for alignD := 0; alignD < 2; alignD++ {
    85  				p := make([]byte, 1023)[alignP:]
    86  				q := make([]byte, 1023)[alignQ:]
    87  
    88  				for i := 0; i < len(p); i++ {
    89  					p[i] = byte(i)
    90  				}
    91  				for i := 0; i < len(q); i++ {
    92  					q[i] = byte(len(q) - i)
    93  				}
    94  				d1 := make([]byte, 1023+alignD)[alignD:]
    95  				d2 := make([]byte, 1023+alignD)[alignD:]
    96  
    97  				ORBytes(d1, p, q)
    98  				safeORBytes(d2, p, q)
    99  				if !bytes.Equal(d1, d2) {
   100  					t.Error("not equal")
   101  				}
   102  			}
   103  		}
   104  	}
   105  }
   106  
   107  // Tests that bit testing works for various alignments.
   108  func TestTest(t *testing.T) {
   109  	for align := 0; align < 2; align++ {
   110  		// Test for bits set in the bulk part
   111  		p := make([]byte, 1023)[align:]
   112  		p[100] = 1
   113  
   114  		if TestBytes(p) != safeTestBytes(p) {
   115  			t.Error("not equal")
   116  		}
   117  		// Test for bits set in the tail part
   118  		q := make([]byte, 1023)[align:]
   119  		q[len(q)-1] = 1
   120  
   121  		if TestBytes(q) != safeTestBytes(q) {
   122  			t.Error("not equal")
   123  		}
   124  	}
   125  }
   126  
   127  // Benchmarks the potentially optimized XOR performance.
   128  func BenchmarkFastXOR1KB(b *testing.B) { benchmarkFastXOR(b, 1024) }
   129  func BenchmarkFastXOR2KB(b *testing.B) { benchmarkFastXOR(b, 2048) }
   130  func BenchmarkFastXOR4KB(b *testing.B) { benchmarkFastXOR(b, 4096) }
   131  
   132  func benchmarkFastXOR(b *testing.B, size int) {
   133  	p, q := make([]byte, size), make([]byte, size)
   134  
   135  	for i := 0; i < b.N; i++ {
   136  		XORBytes(p, p, q)
   137  	}
   138  }
   139  
   140  // Benchmarks the baseline XOR performance.
   141  func BenchmarkBaseXOR1KB(b *testing.B) { benchmarkBaseXOR(b, 1024) }
   142  func BenchmarkBaseXOR2KB(b *testing.B) { benchmarkBaseXOR(b, 2048) }
   143  func BenchmarkBaseXOR4KB(b *testing.B) { benchmarkBaseXOR(b, 4096) }
   144  
   145  func benchmarkBaseXOR(b *testing.B, size int) {
   146  	p, q := make([]byte, size), make([]byte, size)
   147  
   148  	for i := 0; i < b.N; i++ {
   149  		safeXORBytes(p, p, q)
   150  	}
   151  }
   152  
   153  // Benchmarks the potentially optimized AND performance.
   154  func BenchmarkFastAND1KB(b *testing.B) { benchmarkFastAND(b, 1024) }
   155  func BenchmarkFastAND2KB(b *testing.B) { benchmarkFastAND(b, 2048) }
   156  func BenchmarkFastAND4KB(b *testing.B) { benchmarkFastAND(b, 4096) }
   157  
   158  func benchmarkFastAND(b *testing.B, size int) {
   159  	p, q := make([]byte, size), make([]byte, size)
   160  
   161  	for i := 0; i < b.N; i++ {
   162  		ANDBytes(p, p, q)
   163  	}
   164  }
   165  
   166  // Benchmarks the baseline AND performance.
   167  func BenchmarkBaseAND1KB(b *testing.B) { benchmarkBaseAND(b, 1024) }
   168  func BenchmarkBaseAND2KB(b *testing.B) { benchmarkBaseAND(b, 2048) }
   169  func BenchmarkBaseAND4KB(b *testing.B) { benchmarkBaseAND(b, 4096) }
   170  
   171  func benchmarkBaseAND(b *testing.B, size int) {
   172  	p, q := make([]byte, size), make([]byte, size)
   173  
   174  	for i := 0; i < b.N; i++ {
   175  		safeANDBytes(p, p, q)
   176  	}
   177  }
   178  
   179  // Benchmarks the potentially optimized OR performance.
   180  func BenchmarkFastOR1KB(b *testing.B) { benchmarkFastOR(b, 1024) }
   181  func BenchmarkFastOR2KB(b *testing.B) { benchmarkFastOR(b, 2048) }
   182  func BenchmarkFastOR4KB(b *testing.B) { benchmarkFastOR(b, 4096) }
   183  
   184  func benchmarkFastOR(b *testing.B, size int) {
   185  	p, q := make([]byte, size), make([]byte, size)
   186  
   187  	for i := 0; i < b.N; i++ {
   188  		ORBytes(p, p, q)
   189  	}
   190  }
   191  
   192  // Benchmarks the baseline OR performance.
   193  func BenchmarkBaseOR1KB(b *testing.B) { benchmarkBaseOR(b, 1024) }
   194  func BenchmarkBaseOR2KB(b *testing.B) { benchmarkBaseOR(b, 2048) }
   195  func BenchmarkBaseOR4KB(b *testing.B) { benchmarkBaseOR(b, 4096) }
   196  
   197  func benchmarkBaseOR(b *testing.B, size int) {
   198  	p, q := make([]byte, size), make([]byte, size)
   199  
   200  	for i := 0; i < b.N; i++ {
   201  		safeORBytes(p, p, q)
   202  	}
   203  }
   204  
   205  var GloBool bool // Exported global will not be dead-code eliminated, at least not yet.
   206  
   207  // Benchmarks the potentially optimized bit testing performance.
   208  func BenchmarkFastTest1KB(b *testing.B) { benchmarkFastTest(b, 1024) }
   209  func BenchmarkFastTest2KB(b *testing.B) { benchmarkFastTest(b, 2048) }
   210  func BenchmarkFastTest4KB(b *testing.B) { benchmarkFastTest(b, 4096) }
   211  
   212  func benchmarkFastTest(b *testing.B, size int) {
   213  	p := make([]byte, size)
   214  	a := false
   215  	for i := 0; i < b.N; i++ {
   216  		a = a != TestBytes(p)
   217  	}
   218  	GloBool = a // Use of benchmark "result" to prevent total dead code elimination.
   219  }
   220  
   221  // Benchmarks the baseline bit testing performance.
   222  func BenchmarkBaseTest1KB(b *testing.B) { benchmarkBaseTest(b, 1024) }
   223  func BenchmarkBaseTest2KB(b *testing.B) { benchmarkBaseTest(b, 2048) }
   224  func BenchmarkBaseTest4KB(b *testing.B) { benchmarkBaseTest(b, 4096) }
   225  
   226  func benchmarkBaseTest(b *testing.B, size int) {
   227  	p := make([]byte, size)
   228  	a := false
   229  	for i := 0; i < b.N; i++ {
   230  		a = a != safeTestBytes(p)
   231  	}
   232  	GloBool = a // Use of benchmark "result" to prevent total dead code elimination.
   233  }