notary/internal/tlog: update ParseTilePath for tile/H/data/... paths
These paths provide access to the raw record data,
in the form returned by /lookup,
separated by blank lines.
Change-Id: Ib8aa7d45815a16043d5f58f0e81b0678701ff2ea
Reviewed-on: https://go-review.googlesource.com/c/exp/+/172412
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
diff --git a/notary/internal/tlog/tile.go b/notary/internal/tlog/tile.go
index 1885e8e..694d89c 100644
--- a/notary/internal/tlog/tile.go
+++ b/notary/internal/tlog/tile.go
@@ -29,10 +29,14 @@
// Tile{H: 3, L: 4, N: 1234067, W: 8}'s path
// is tile/3/4/x001/x234/067.
// See Tile's Path method and the ParseTilePath function.
+//
+// The special level L=-1 holds raw record data instead of hashes.
+// In this case, the level encodes into a tile path as the path element
+// "data" instead of "-1".
type Tile struct {
H int // height of tile (1 ≤ H ≤ 30)
- L int // level in tiling (1 ≤ H ≤ 63)
- N int64 // number within level (unbounded)
+ L int // level in tiling (-1 ≤ L ≤ 63)
+ N int64 // number within level (0 ≤ N, unbounded)
W int // width of tile (1 ≤ W ≤ 2**H; 2**H is complete tile)
}
@@ -168,7 +172,13 @@
if t.W != 1<<uint(t.H) {
pStr = fmt.Sprintf(".p/%d", t.W)
}
- return fmt.Sprintf("tile/%d/%d/%s%s", t.H, t.L, nStr, pStr)
+ var L string
+ if t.L == -1 {
+ L = "data"
+ } else {
+ L = fmt.Sprintf("%d", t.L)
+ }
+ return fmt.Sprintf("tile/%d/%s/%s%s", t.H, L, nStr, pStr)
}
// ParseTilePath parses a tile coordinate path.
@@ -178,6 +188,11 @@
return Tile{}, &badPathError{path}
}
h, err1 := strconv.Atoi(f[1])
+ isData := false
+ if f[2] == "data" {
+ isData = true
+ f[2] = "0"
+ }
l, err2 := strconv.Atoi(f[2])
if err1 != nil || err2 != nil || h < 1 || l < 0 || h > 30 {
return Tile{}, &badPathError{path}
@@ -201,6 +216,9 @@
}
n = n*pathBase + int64(nn)
}
+ if isData {
+ l = -1
+ }
t := Tile{H: h, L: l, N: n, W: w}
if path != t.Path() {
return Tile{}, &badPathError{path}
diff --git a/notary/internal/tlog/tlog_test.go b/notary/internal/tlog/tlog_test.go
index 3dad1a1..584e728 100644
--- a/notary/internal/tlog/tlog_test.go
+++ b/notary/internal/tlog/tlog_test.go
@@ -238,18 +238,31 @@
{"tile/3/5/x123/x456/078", Tile{3, 5, 123456078, 8}},
{"tile/3/5/x123/x456/078.p/2", Tile{3, 5, 123456078, 2}},
{"tile/1/0/x003/x057/500", Tile{1, 0, 3057500, 2}},
+ {"tile/3/5/123/456/078", Tile{}},
+ {"tile/3/-1/123/456/078", Tile{}},
+ {"tile/1/data/x003/x057/500", Tile{1, -1, 3057500, 2}},
}
func TestTilePath(t *testing.T) {
for _, tt := range tilePaths {
- p := tt.tile.Path()
- if p != tt.path {
- t.Errorf("%+v.Path() = %q, want %q", tt.tile, p, tt.path)
+ if tt.tile.H > 0 {
+ p := tt.tile.Path()
+ if p != tt.path {
+ t.Errorf("%+v.Path() = %q, want %q", tt.tile, p, tt.path)
+ }
}
tile, err := ParseTilePath(tt.path)
if err != nil {
+ if tt.tile.H == 0 {
+ // Expected error.
+ continue
+ }
t.Errorf("ParseTilePath(%q): %v", tt.path, err)
} else if tile != tt.tile {
+ if tt.tile.H == 0 {
+ t.Errorf("ParseTilePath(%q): expected error, got %+v", tt.path, tt.tile)
+ continue
+ }
t.Errorf("ParseTilePath(%q) = %+v, want %+v", tt.path, tile, tt.tile)
}
}