Skip to content

Commit

Permalink
introduces ByteSortable method in Revision
Browse files Browse the repository at this point in the history
This helps determine if the string representation
of the revision is byte-sortable. This helps
being able to determine if a revision can be
serialized to databases that rely on byte-sorting.
  • Loading branch information
vroldanbet committed Nov 12, 2024
1 parent ead5dc1 commit bc265a8
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 0 deletions.
4 changes: 4 additions & 0 deletions internal/datastore/postgres/revisions.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,10 @@ type postgresRevision struct {
optionalMetadata map[string]any
}

func (pr postgresRevision) ByteSortable() bool {
return false
}

func (pr postgresRevision) Equal(rhsRaw datastore.Revision) bool {
rhs, ok := rhsRaw.(postgresRevision)
return ok && pr.snapshot.Equal(rhs.snapshot)
Expand Down
83 changes: 83 additions & 0 deletions internal/datastore/revisions/commonrevision_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package revisions

import (
"bytes"
"sort"
"strings"
"testing"

Expand Down Expand Up @@ -246,3 +248,84 @@ func TestHLCRevisionParsing(t *testing.T) {
})
}
}

func TestRevisionByteSortable(t *testing.T) {
tcs := []struct {
left string
right string
leftFirst bool
}{
{
"1",
"2",
true,
},
{
"2",
"1",
false,
},
{
"1",
"1",
true,
},
{
"1.0000000004",
"1",
false,
},
{
"1",
"1.0000000004",
true,
},
{
"1.0000000004",
"1.0000000004",
true,
},
{
"1.1000000000",
"1.0000000001",
false,
},
}

for _, tc := range tcs {
t.Run(tc.left+"_"+tc.right, func(t *testing.T) {
for kind, supportsDecimals := range kinds {
t.Run(string(kind), func(t *testing.T) {
if !supportsDecimals && strings.Contains(tc.left, ".") {
t.Skip("does not support decimals")
}

if !supportsDecimals && strings.Contains(tc.right, ".") {
t.Skip("does not support decimals")
}
parser := RevisionParser(kind)

leftRev, err := parser(tc.left)
require.NoError(t, err)

rightRev, err := parser(tc.right)
require.NoError(t, err)

if !leftRev.ByteSortable() || !rightRev.ByteSortable() {
t.Skip("does not support byt sorting")
}

toSort := []string{leftRev.String(), rightRev.String()}
sort.Strings(toSort)
if tc.leftFirst {
require.Equal(t, leftRev.String(), toSort[0])
require.Equal(t, 0, bytes.Compare([]byte(leftRev.String()), []byte(toSort[0])))
} else {
require.Equal(t, rightRev.String(), toSort[0])
require.Equal(t, 0, bytes.Compare([]byte(rightRev.String()), []byte(toSort[0])))
}
})
}
})
}
}
4 changes: 4 additions & 0 deletions internal/datastore/revisions/hlcrevision.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ func NewHLCForTime(time time.Time) HLCRevision {
return HLCRevision{time.UnixNano(), logicalClockOffset}
}

func (hlc HLCRevision) ByteSortable() bool {
return true
}

func (hlc HLCRevision) Equal(rhs datastore.Revision) bool {
if rhs == datastore.NoRevision {
rhs = zeroHLC
Expand Down
4 changes: 4 additions & 0 deletions internal/datastore/revisions/timestamprevision.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ func parseTimestampRevisionString(revisionStr string) (rev datastore.Revision, e
return TimestampRevision(parsed), nil
}

func (ir TimestampRevision) ByteSortable() bool {
return true
}

func (ir TimestampRevision) Equal(rhs datastore.Revision) bool {
if rhs == datastore.NoRevision {
rhs = zeroTimestampRevision
Expand Down
4 changes: 4 additions & 0 deletions internal/datastore/revisions/txidrevision.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ func parseTransactionIDRevisionString(revisionStr string) (rev datastore.Revisio
return TransactionIDRevision(parsed), nil
}

func (ir TransactionIDRevision) ByteSortable() bool {
return true
}

func (ir TransactionIDRevision) Equal(rhs datastore.Revision) bool {
if rhs == datastore.NoRevision {
rhs = zeroTransactionIDRevision
Expand Down
7 changes: 7 additions & 0 deletions pkg/datastore/datastore.go
Original file line number Diff line number Diff line change
Expand Up @@ -817,10 +817,17 @@ type Revision interface {

// LessThan returns whether the receiver is probably less than the right hand side.
LessThan(Revision) bool

// ByteSortable returns true if the string representation of the Revision is byte sortable, false otherwise.
ByteSortable() bool
}

type nilRevision struct{}

func (nilRevision) ByteSortable() bool {
return false
}

func (nilRevision) Equal(rhs Revision) bool {
return rhs == NoRevision
}
Expand Down

0 comments on commit bc265a8

Please sign in to comment.