Skip to content

Commit

Permalink
enhance #10 : avoid allocations on parseUUID
Browse files Browse the repository at this point in the history
  • Loading branch information
ashwingopalsamy authored Dec 26, 2024
2 parents a206a17 + 4c42601 commit 4ccd19c
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 5 deletions.
27 changes: 22 additions & 5 deletions helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"encoding/hex"
"errors"
"fmt"
"strings"
)

// Helper function to encode timestamp into the UUID byte array.
Expand All @@ -29,14 +28,32 @@ func decodeTimestamp(uuidBytes []byte) uint64 {
uint64(uuidBytes[3])<<16 | uint64(uuidBytes[4])<<8 | uint64(uuidBytes[5])
}

// Helper function to parse and sanitize a UUID string.
// Helper function to parse and sanitize a UUID string.
func parseUUID(uuid string) ([]byte, error) {
uuid = strings.ReplaceAll(uuid, "-", "")
if len(uuid) != 32 {
switch len(uuid) {
case 32:
// Fast path for UUIDs without dashes
return hex.DecodeString(uuid)
case 36:
// Validate dash positions
if uuid[8] != '-' || uuid[13] != '-' || uuid[18] != '-' || uuid[23] != '-' {
return nil, errors.New("invalid UUID format")
}

// Remove dashes while copying characters
result := make([]byte, 32)
j := 0
for i := 0; i < len(uuid); i++ {
if uuid[i] != '-' {
result[j] = uuid[i]
j++
}
}
return hex.DecodeString(string(result))
default:
return nil, errors.New("invalid UUID length")
}

return hex.DecodeString(uuid)
}

// Helper function to check if a UUID is all zeros.
Expand Down
72 changes: 72 additions & 0 deletions uuidv8_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -720,3 +720,75 @@ func TestUUIDv8_Scan_EdgeCases(t *testing.T) {
})
}
}

func TestFromString_InvalidInputs(t *testing.T) {
tests := []string{
"123", // Too short
"123e4567e89b12d3a4564266141740000000", // Too long
"123e4567e89b12d3a45642661417400g", // Invalid character
"123e-4567-e89b-12d3-a456-426614174000", // Misplaced dashes
"123e4567-e89b-12d3-a456-426614174000-", // Extra dash at the end
"--123e4567-e89b-12d3-a456-426614174000", // Extra dash at the start
"123e4567-e89b-12d3-a456-42-6614174000", // Randomly placed dash
"------------------------------------", // 36 dashes
"9a3d4049-0e2c-8080-0102-030405060000", // Valid UUID with dashes
}

for _, input := range tests {
t.Run("Testing UUID: "+input, func(t *testing.T) {
_, err := uuidv8.FromString(input)
// The last case is valid; others should fail
if input == "9a3d4049-0e2c-8080-0102-030405060000" {
if err != nil {
t.Errorf("Expected valid UUID but got error for input: %s", input)
}
} else {
if err == nil {
t.Errorf("Expected error, got nil for input: %s", input)
}
}
})
}
}

func TestFromStringOrNil_InvalidInputs(t *testing.T) {
tests := []string{
"123", // Too short
"123e4567e89b12d3a4564266141740000000", // Too long
"123e4567e89b12d3a45642661417400g", // Invalid character
"", // Empty string
"123e4567-e89b-12d3-a456-426614174000-", // Extra dash at the end
"--123e4567-e89b-12d3-a456-426614174000", // Extra dash at the start
"123e4567-e89b-12d3-a456-42-6614174000", // Randomly placed dash
}

for _, input := range tests {
t.Run("Invalid UUID "+input, func(t *testing.T) {
result := uuidv8.FromStringOrNil(input)
if result != nil {
t.Errorf("Expected nil for input: %s, got %v", input, result)
}
})
}
}

func TestIsValidUUIDv8_InvalidUUIDs(t *testing.T) {
invalidUUIDs := []string{
"123", // Too short
"123e4567e89b12d3a4564266141740000000", // Too long
"123e4567e89b12d3a45642661417400g", // Invalid character
"", // Empty string
"123e4567-e89b-12d3-a456-426614174000-", // Extra dash at the end
"--123e4567-e89b-12d3-a456-426614174000", // Extra dash at the start
"123e4567-e89b-12d3-a456-42-6614174000", // Randomly placed dash

}

for _, uuid := range invalidUUIDs {
t.Run("Invalid UUID "+uuid, func(t *testing.T) {
if uuidv8.IsValidUUIDv8(uuid) {
t.Errorf("Expected UUID %s to be invalid", uuid)
}
})
}
}

0 comments on commit 4ccd19c

Please sign in to comment.