Added blockdigest class to store digests more efficiently. This has the nice side...
authormishaz <misha@curoverse.com>
Tue, 23 Dec 2014 23:55:12 +0000 (23:55 +0000)
committerTom Clegg <tom@curoverse.com>
Fri, 13 Feb 2015 21:23:51 +0000 (16:23 -0500)
sdk/go/blockdigest/blockdigest.go [new file with mode: 0644]
sdk/go/blockdigest/blockdigest_test.go [new file with mode: 0644]

diff --git a/sdk/go/blockdigest/blockdigest.go b/sdk/go/blockdigest/blockdigest.go
new file mode 100644 (file)
index 0000000..5225af6
--- /dev/null
@@ -0,0 +1,45 @@
+/* Stores a Block Locator Digest compactly. Can be used as a map key. */
+
+package blockdigest
+
+import (
+       "fmt"
+       "log"
+       "strconv"
+)
+
+// Stores a Block Locator Digest compactly, up to 128 bits.
+// Can be used as a map key.
+type BlockDigest struct {
+       h uint64
+       l uint64
+}
+
+func (d *BlockDigest) ToString() (s string) {
+       return fmt.Sprintf("%016x%016x", d.h, d.l)
+}
+
+// Will create a new BlockDigest unless an error is encountered.
+func FromString(s string) (dig BlockDigest, err error) {
+       if len(s) != 32 {
+               err = fmt.Errorf("Block digest should be exactly 32 characters but this one is %d: %s", len(s), s)
+               return
+       }
+
+       var d BlockDigest
+       d.h, err = strconv.ParseUint(s[:16], 16, 64)
+       if err != nil {return}
+       d.l, err = strconv.ParseUint(s[16:], 16, 64)
+       if err != nil {return}
+       dig = d
+       return
+}
+
+// Will fatal with the error if an error is encountered
+func AssertFromString(s string) BlockDigest {
+       d, err := FromString(s)
+       if err != nil {
+               log.Fatalf("Error creating BlockDigest from %s: %v", s, err)
+       }
+       return d
+}
diff --git a/sdk/go/blockdigest/blockdigest_test.go b/sdk/go/blockdigest/blockdigest_test.go
new file mode 100644 (file)
index 0000000..9081bb8
--- /dev/null
@@ -0,0 +1,45 @@
+package blockdigest
+
+import (
+       "strings"
+       "testing"
+)
+
+func expectValidDigestString(t *testing.T, s string) {
+       bd, err := FromString(s)
+       if err != nil {
+               t.Fatalf("Expected %s to produce a valid BlockDigest but instead got error: %v", s, err)
+       }
+
+       expected := strings.ToLower(s)
+               
+       if expected != bd.ToString() {
+               t.Fatalf("Expected %s to be returned by FromString(%s).ToString() but instead we received %s", expected, s, bd.ToString())
+       }
+}
+
+func expectInvalidDigestString(t *testing.T, s string) {
+       _, err := FromString(s)
+       if err == nil {
+               t.Fatalf("Expected %s to be an invalid BlockDigest, but did not receive an error", s)
+       }
+}
+
+func TestValidDigestStrings(t *testing.T) {
+       expectValidDigestString(t, "01234567890123456789abcdefabcdef")
+       expectValidDigestString(t, "01234567890123456789ABCDEFABCDEF")
+       expectValidDigestString(t, "01234567890123456789AbCdEfaBcDeF")
+}
+
+func TestInvalidDigestStrings(t *testing.T) {
+       expectInvalidDigestString(t, "01234567890123456789abcdefabcdeg")
+       expectInvalidDigestString(t, "01234567890123456789abcdefabcde")
+       expectInvalidDigestString(t, "01234567890123456789abcdefabcdefa")
+       expectInvalidDigestString(t, "g1234567890123456789abcdefabcdef")
+}
+
+func TestBlockDigestWorksAsMapKey(t *testing.T) {
+       m := make(map[BlockDigest]int)
+       bd := AssertFromString("01234567890123456789abcdefabcdef")
+       m[bd] = 5
+}