github.com/philpearl/intern@v0.0.1/intern_test.go (about)

     1  package intern_test
     2  
     3  import (
     4  	"reflect"
     5  	"strconv"
     6  	"testing"
     7  	"unsafe"
     8  
     9  	"github.com/philpearl/intern"
    10  	"github.com/stretchr/testify/assert"
    11  )
    12  
    13  func TestBasic(t *testing.T) {
    14  	i := intern.New(16)
    15  
    16  	hat := i.Deduplicate("hat")
    17  	sat := i.Deduplicate("sat")
    18  	hat2 := i.Deduplicate("hat")
    19  
    20  	if hat != hat2 || hat != "hat" {
    21  		t.Errorf("Hat is wrong. Have %s and %s", hat, hat2)
    22  	}
    23  
    24  	if sat != "sat" {
    25  		t.Errorf("sat is wrong. Have %s", sat)
    26  	}
    27  
    28  	if datapointer(hat) != datapointer(hat2) {
    29  		t.Errorf("hat pointers differ")
    30  	}
    31  }
    32  
    33  func TestGrowth(t *testing.T) {
    34  	in := intern.New(15)
    35  
    36  	for i := 0; i < 1000; i++ {
    37  		val := strconv.Itoa(i)
    38  		assert.Equal(t, val, in.Deduplicate(val))
    39  	}
    40  
    41  	for i := 0; i < 1000; i++ {
    42  		val := strconv.Itoa(i)
    43  		assert.Equal(t, val, in.Deduplicate(val))
    44  	}
    45  }
    46  
    47  func TestGrowth2(t *testing.T) {
    48  	in := intern.New(15)
    49  
    50  	for i := 0; i < 1000; i++ {
    51  		val := strconv.Itoa(i)
    52  		assert.Equal(t, val, in.Deduplicate(val))
    53  		assert.Equal(t, val, in.Deduplicate(val))
    54  	}
    55  }
    56  
    57  func TestNoNew(t *testing.T) {
    58  	in := &intern.Intern{}
    59  
    60  	for i := 0; i < 1000; i++ {
    61  		val := strconv.Itoa(i)
    62  		assert.Equal(t, val, in.Deduplicate(val))
    63  		assert.Equal(t, val, in.Deduplicate(val))
    64  	}
    65  }
    66  
    67  func datapointer(val string) uintptr {
    68  	return (*reflect.StringHeader)(unsafe.Pointer(&val)).Data
    69  }
    70  
    71  func TestResize(t *testing.T) {
    72  	i := intern.New(16)
    73  
    74  	for k := 0; k < 2; k++ {
    75  		for j := 0; j < 256; j++ {
    76  			i.Deduplicate(strconv.Itoa(j))
    77  		}
    78  		if i.Len() != 256 {
    79  			t.Errorf("expected 256 unique strings. Have %d", i.Len())
    80  		}
    81  		if i.Cap() != 512 {
    82  			t.Errorf("expected 512 capacity. Have %d", i.Cap())
    83  		}
    84  	}
    85  }
    86  
    87  func BenchmarkIntern(b *testing.B) {
    88  	s := make([]string, b.N)
    89  	for i := range s {
    90  		s[i] = strconv.Itoa(i)
    91  	}
    92  
    93  	intern := intern.New(16)
    94  
    95  	b.ReportAllocs()
    96  	b.ResetTimer()
    97  
    98  	var dedupe string
    99  	for _, v := range s {
   100  		dedupe = intern.Deduplicate(v)
   101  	}
   102  
   103  	if dedupe != strconv.Itoa(b.N-1) {
   104  		b.Errorf("last dedupe not as expected. Have %s expected %d", dedupe, b.N-1)
   105  	}
   106  }
   107  
   108  func BenchmarkInternBasic(b *testing.B) {
   109  	s := make([]string, b.N)
   110  	for i := range s {
   111  		s[i] = strconv.Itoa(i)
   112  	}
   113  
   114  	intern := make(map[string]string)
   115  
   116  	b.ReportAllocs()
   117  	b.ResetTimer()
   118  
   119  	var dedupe string
   120  	var ok bool
   121  	for _, v := range s {
   122  		dedupe, ok = intern[v]
   123  		if !ok {
   124  			intern[v] = v
   125  			dedupe = v
   126  		}
   127  	}
   128  
   129  	if dedupe != strconv.Itoa(b.N-1) {
   130  		b.Errorf("last dedupe not as expected. Have %s expected %d", dedupe, b.N-1)
   131  	}
   132  }