github.com/grailbio/base@v0.0.11/diagnostic/memsize/interval_set_test.go (about)

     1  package memsize
     2  
     3  import (
     4  	"math/rand"
     5  	"testing"
     6  )
     7  
     8  func TestIntervalSet(t *testing.T) {
     9  	tests := []struct {
    10  		data            []interval
    11  		expectedCovered []int
    12  	}{
    13  		{
    14  			data:            []interval{{1, 10}},
    15  			expectedCovered: []int{10},
    16  		},
    17  		{
    18  			data:            []interval{{1, 10}, {11, 10}},
    19  			expectedCovered: []int{10, 20},
    20  		},
    21  		{
    22  			data:            []interval{{1, 10}, {5, 10}},
    23  			expectedCovered: []int{10, 14},
    24  		},
    25  		{
    26  			data:            []interval{{1, 10}, {5, 10}, {6, 9}, {6, 10}, {100, 1}, {100, 2}, {101, 1}},
    27  			expectedCovered: []int{10, 14, 14, 15, 16, 17, 17},
    28  		},
    29  		{
    30  			data:            []interval{{100, 1}, {99, 1}, {99, 2}, {0, 10}, {10, 10}},
    31  			expectedCovered: []int{1, 2, 2, 12, 22},
    32  		},
    33  	}
    34  
    35  	for testId, test := range tests {
    36  		for numToAdd := range test.data {
    37  			var set intervalSet
    38  			for i := 0; i <= numToAdd; i++ {
    39  				newInterval := test.data[i]
    40  				set.add(newInterval)
    41  			}
    42  			got := set.totalCovered()
    43  			if got != test.expectedCovered[numToAdd] {
    44  				t.Errorf("test: %d, query: %d: got %v, expected %v", testId, numToAdd, got, test.expectedCovered[numToAdd])
    45  			}
    46  		}
    47  	}
    48  }
    49  
    50  func TestEmptySet(t *testing.T) {
    51  	var set intervalSet
    52  	if got := set.totalCovered(); got != 0 {
    53  		t.Errorf("empty set should have 0 coverage.  got %d", got)
    54  	}
    55  }
    56  
    57  // TestRandomAddition creates a random slice of intervals and adds them in random order to the intervalSet.
    58  // It periodically checks TotalCovered() against another implementation of interval set.
    59  func TestRandomAddition(t *testing.T) {
    60  	tests := []struct {
    61  		setsize         int
    62  		testrepeats     int
    63  		size            int
    64  		intervalrepeats int
    65  		sampleProb      float64
    66  	}{
    67  		{
    68  			setsize:         100,
    69  			testrepeats:     100,
    70  			size:            1,
    71  			intervalrepeats: 2,
    72  			sampleProb:      .2,
    73  		},
    74  		{
    75  			setsize:         1000,
    76  			testrepeats:     100,
    77  			size:            3,
    78  			intervalrepeats: 2,
    79  			sampleProb:      .2,
    80  		},
    81  		{
    82  			setsize:         1000,
    83  			testrepeats:     100,
    84  			size:            3,
    85  			intervalrepeats: 2,
    86  			sampleProb:      0,
    87  		},
    88  	}
    89  
    90  	for _, test := range tests {
    91  		for testRepeat := 0; testRepeat < test.testrepeats; testRepeat++ {
    92  			r := rand.New(rand.NewSource(int64(testRepeat)))
    93  			var intervals []interval
    94  			for i := 0; i < test.setsize; i++ {
    95  				for j := 0; j < test.intervalrepeats; j++ {
    96  					intervals = append(intervals, interval{start: uintptr(i), length: int64(test.size)})
    97  				}
    98  			}
    99  			shuffle(intervals, int64(testRepeat))
   100  			set := intervalSet{}
   101  			coveredMap := make(map[uintptr]struct{})
   102  			for _, x := range intervals {
   103  				set.add(x)
   104  				for j := uintptr(0); j < uintptr(x.length); j++ {
   105  					coveredMap[x.start+j] = struct{}{}
   106  				}
   107  				if r.Float64() < test.sampleProb {
   108  					gotCovered := set.totalCovered()
   109  					if gotCovered != len(coveredMap) {
   110  						t.Errorf("set.Covered()=%d, len(coveredMap) = %d", gotCovered, len(coveredMap))
   111  					}
   112  				}
   113  			}
   114  
   115  			if gotSize := set.totalCovered(); gotSize != test.size+test.setsize-1 {
   116  				t.Errorf("total covering - got: %d, expected %d", gotSize, test.setsize+test.setsize-1)
   117  			}
   118  		}
   119  	}
   120  }
   121  
   122  // randomly shuffle a set of intervals
   123  func shuffle(set []interval, seed int64) {
   124  	r := rand.New(rand.NewSource(seed))
   125  	r.Shuffle(len(set), func(i, j int) {
   126  		set[i], set[j] = set[j], set[i]
   127  	})
   128  }