github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/internal/datastore/revisions/hlcrevision_test.go (about)

     1  package revisions
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/shopspring/decimal"
     8  	"github.com/stretchr/testify/require"
     9  )
    10  
    11  func TestNewForHLC(t *testing.T) {
    12  	tcs := []string{
    13  		"1",
    14  		"2",
    15  		"42",
    16  		"1257894000000000000",
    17  		"-1",
    18  		"1.0000000023",
    19  		"1703283409994227985.0000000004",
    20  		"1703283409994227985.0000000040",
    21  		"1703283409994227985.0010000000",
    22  	}
    23  
    24  	for _, tc := range tcs {
    25  		t.Run(tc, func(t *testing.T) {
    26  			d, err := decimal.NewFromString(tc)
    27  			require.NoError(t, err)
    28  
    29  			rev, err := NewForHLC(d)
    30  			require.NoError(t, err)
    31  			require.Equal(t, tc, rev.String())
    32  		})
    33  	}
    34  }
    35  
    36  func TestTimestampNanoSec(t *testing.T) {
    37  	tcs := map[string]int64{
    38  		"1":                              1,
    39  		"2":                              2,
    40  		"42":                             42,
    41  		"1257894000000000000":            1257894000000000000,
    42  		"-1":                             -1,
    43  		"1.0000000023":                   1,
    44  		"9223372036854775807.0000000002": 9223372036854775807,
    45  		"1703283409994227985.0000000004": 1703283409994227985,
    46  		"1703283409994227985.0000000040": 1703283409994227985,
    47  	}
    48  
    49  	for tc, nano := range tcs {
    50  		t.Run(tc, func(t *testing.T) {
    51  			rev, err := HLCRevisionFromString(tc)
    52  			require.NoError(t, err)
    53  
    54  			require.Equal(t, nano, rev.TimestampNanoSec())
    55  		})
    56  	}
    57  }
    58  
    59  func TestInexactFloat64(t *testing.T) {
    60  	tcs := map[string]float64{
    61  		"1":                              1,
    62  		"2":                              2,
    63  		"42":                             42,
    64  		"1257894000000000000":            1257894000000000000,
    65  		"-1":                             -1,
    66  		"1.0000000023":                   1.0000000023,
    67  		"9223372036854775807.0000000002": 9223372036854775807.0000000002,
    68  		"1703283409994227985.0000000004": 1703283409994227985.0000000004,
    69  		"1703283409994227985.0000000040": 1703283409994227985.000000004,
    70  		"1703283409994227985.000000004":  1703283409994227985.000000004,
    71  		"1703283409994227985.0010":       1703283409994227985.001,
    72  		"1703283409994227985.0010000000": 1703283409994227985.001,
    73  		"1703283409994227985.001":        1703283409994227985.001,
    74  	}
    75  
    76  	for tc, floatValue := range tcs {
    77  		t.Run(tc, func(t *testing.T) {
    78  			rev, err := HLCRevisionFromString(tc)
    79  			require.NoError(t, err)
    80  
    81  			require.Equal(t, floatValue, rev.InexactFloat64())
    82  		})
    83  	}
    84  }
    85  
    86  func TestNewHLCForTime(t *testing.T) {
    87  	time := time.Now()
    88  	rev := NewForTime(time)
    89  	require.Equal(t, time.UnixNano(), rev.TimestampNanoSec())
    90  }
    91  
    92  func TestHLCKeyEquals(t *testing.T) {
    93  	tcs := []struct {
    94  		left    string
    95  		right   string
    96  		isEqual bool
    97  	}{
    98  		{
    99  			"1", "2", false,
   100  		},
   101  		{
   102  			"2", "1", false,
   103  		},
   104  		{
   105  			"2", "2", true,
   106  		},
   107  		{
   108  			"1", "1.0000000005", false,
   109  		},
   110  		{
   111  			"1.0000000001", "1.0000000001", true,
   112  		},
   113  		{
   114  			"1.0000000001", "1", false,
   115  		},
   116  		{
   117  			"1703283409994227985.0000000004", "1703283409994227985.0000000005", false,
   118  		},
   119  		{
   120  			"1703283409994227985.0000000005", "1703283409994227985.0000000004", false,
   121  		},
   122  		{
   123  			"1703283409994227985.0000000014", "1703283409994227985.0000000005", false,
   124  		},
   125  		{
   126  			"1703283409994227985.0000000005", "1703283409994227985.0000000005", true,
   127  		},
   128  		{
   129  			"1703283409994227985.0000000050", "1703283409994227985.0000000050", true,
   130  		},
   131  		{
   132  			"1703283409994227985.0000000050", "1703283409994227985.0000000005", false,
   133  		},
   134  		{
   135  			"1703283409994227985.000000005", "1703283409994227985.0000000050", true,
   136  		},
   137  	}
   138  
   139  	for _, tc := range tcs {
   140  		t.Run(tc.left+"-"+tc.right, func(t *testing.T) {
   141  			left, err := HLCRevisionFromString(tc.left)
   142  			require.NoError(t, err)
   143  
   144  			right, err := HLCRevisionFromString(tc.right)
   145  			require.NoError(t, err)
   146  
   147  			lk := HLCKeyFunc(left)
   148  			rk := HLCKeyFunc(right)
   149  
   150  			require.Equal(t, tc.isEqual, lk == rk)
   151  		})
   152  	}
   153  }
   154  
   155  func TestHLCKeyLessThanFunc(t *testing.T) {
   156  	tcs := []struct {
   157  		left       string
   158  		right      string
   159  		isLessThan bool
   160  	}{
   161  		{
   162  			"1", "2", true,
   163  		},
   164  		{
   165  			"2", "1", false,
   166  		},
   167  		{
   168  			"2", "2", false,
   169  		},
   170  		{
   171  			"1", "1.0000000005", true,
   172  		},
   173  		{
   174  			"1.0000000001", "1.0000000001", false,
   175  		},
   176  		{
   177  			"1.0000000001", "1", false,
   178  		},
   179  		{
   180  			"1703283409994227985.0000000004", "1703283409994227985.0000000005", true,
   181  		},
   182  		{
   183  			"1703283409994227985.0000000005", "1703283409994227985.0000000004", false,
   184  		},
   185  		{
   186  			"1703283409994227985.0000000014", "1703283409994227985.0000000005", false,
   187  		},
   188  		{
   189  			"1703283409994227985.0000000005", "1703283409994227985.0000000014", true,
   190  		},
   191  	}
   192  
   193  	for _, tc := range tcs {
   194  		t.Run(tc.left+"-"+tc.right, func(t *testing.T) {
   195  			left, err := HLCRevisionFromString(tc.left)
   196  			require.NoError(t, err)
   197  
   198  			right, err := HLCRevisionFromString(tc.right)
   199  			require.NoError(t, err)
   200  
   201  			lk := HLCKeyFunc(left)
   202  			rk := HLCKeyFunc(right)
   203  
   204  			require.Equal(t, tc.isLessThan, HLCKeyLessThanFunc(lk, rk))
   205  		})
   206  	}
   207  }
   208  
   209  func BenchmarkHLCParsing(b *testing.B) {
   210  	tcs := []string{
   211  		"1",
   212  		"2",
   213  		"42",
   214  		"1257894000000000000",
   215  		"-1",
   216  		"9223372036854775807.1000000025",
   217  		"1703283409994227985.0000000004",
   218  	}
   219  
   220  	for _, tc := range tcs {
   221  		b.Run(tc, func(b *testing.B) {
   222  			for i := 0; i < b.N; i++ {
   223  				_, err := HLCRevisionFromString(tc)
   224  				if err != nil {
   225  					b.Fatal(err)
   226  				}
   227  			}
   228  		})
   229  	}
   230  }
   231  
   232  func BenchmarkHLCLessThan(b *testing.B) {
   233  	tcs := []struct {
   234  		left  string
   235  		right string
   236  	}{
   237  		{
   238  			"1", "2",
   239  		},
   240  		{
   241  			"2", "1",
   242  		},
   243  		{
   244  			"2", "2",
   245  		},
   246  		{
   247  			"1703283409994227985.0000000004", "1703283409994227985.0000000005",
   248  		},
   249  		{
   250  			"1703283409994227985.0000000005", "1703283409994227985.0000000004",
   251  		},
   252  	}
   253  
   254  	for _, tc := range tcs {
   255  		b.Run(tc.left+"-"+tc.right, func(b *testing.B) {
   256  			left, err := HLCRevisionFromString(tc.left)
   257  			if err != nil {
   258  				b.Fatal(err)
   259  			}
   260  
   261  			right, err := HLCRevisionFromString(tc.right)
   262  			if err != nil {
   263  				b.Fatal(err)
   264  			}
   265  
   266  			b.ResetTimer()
   267  			left.LessThan(right)
   268  		})
   269  	}
   270  }
   271  
   272  func BenchmarkHLCLessThanFunc(b *testing.B) {
   273  	tcs := []struct {
   274  		left  string
   275  		right string
   276  	}{
   277  		{
   278  			"1", "2",
   279  		},
   280  		{
   281  			"2", "1",
   282  		},
   283  		{
   284  			"2", "2",
   285  		},
   286  		{
   287  			"1703283409994227985.0000000001", "1703283409994227985.0000000001",
   288  		},
   289  		{
   290  			"1703283409994227985.0000000004", "1703283409994227985.0000000005",
   291  		},
   292  		{
   293  			"1703283409994227985.0000000005", "1703283409994227985.0000000004",
   294  		},
   295  	}
   296  
   297  	for _, tc := range tcs {
   298  		b.Run(tc.left+"-"+tc.right, func(b *testing.B) {
   299  			left, err := HLCRevisionFromString(tc.left)
   300  			if err != nil {
   301  				b.Fatal(err)
   302  			}
   303  
   304  			right, err := HLCRevisionFromString(tc.right)
   305  			if err != nil {
   306  				b.Fatal(err)
   307  			}
   308  
   309  			b.ResetTimer()
   310  			lk := HLCKeyFunc(left)
   311  			rk := HLCKeyFunc(right)
   312  
   313  			for i := 0; i < b.N; i++ {
   314  				HLCKeyLessThanFunc(lk, rk)
   315  			}
   316  		})
   317  	}
   318  }