ref: 5ef52294f90c51697bd3f918b3c3ed83baff657a
parent: 37fb2d43e5d3ecfd1f16324556d85e202fadcc73
author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
date: Mon Apr 11 07:49:02 EDT 2016
Add Node.ID Fixes #2071
--- a/hugolib/node.go
+++ b/hugolib/node.go
@@ -14,10 +14,12 @@
package hugolib
import (
- "github.com/spf13/cast"
"html/template"
"sync"
+ "sync/atomic"
"time"
+
+ "github.com/spf13/cast"
)
type Node struct {@@ -37,6 +39,24 @@
paginator *Pager
paginatorInit sync.Once
scratch *Scratch
+ id int
+ idInit sync.Once
+}
+
+// This should probably be owned by Site and new ids assigned on creation,
+// but that would lead to massive changes; do it simple for now.
+var nodeIDCounter uint64
+
+func nextNodeID() int {+ return int(atomic.AddUint64(&nodeIDCounter, 1))
+}
+
+// ID returns an integer that identifies this Node.
+// This is unique for a given Hugo build, but must not be considered stable.
+// See UniqueID on Page for an identify that is stable for repeated builds.
+func (n *Node) ID() int {+ n.idInit.Do(func() { n.id = nextNodeID() })+ return n.id
}
func (n *Node) Now() time.Time {--- a/hugolib/node_test.go
+++ b/hugolib/node_test.go
@@ -14,8 +14,11 @@
package hugolib
import (
+ "sync"
"testing"
"time"
+
+ "github.com/stretchr/testify/assert"
)
func TestNodeSimpleMethods(t *testing.T) {@@ -37,4 +40,29 @@
t.Errorf("[%d] Node method error", i)}
}
+}
+
+func TestNodeID(t *testing.T) {+ t.Parallel()
+
+ n1 := &Node{}+ n2 := &Node{}+
+ assert.True(t, n1.ID() > 0)
+ assert.Equal(t, n1.ID(), n1.ID())
+ assert.True(t, n2.ID() > n1.ID())
+
+ var wg sync.WaitGroup
+
+ for i := 1; i <= 10; i++ {+ wg.Add(1)
+ go func(j int) {+ for k := 0; k < 10; k++ {+ n := &Node{}+ assert.True(t, n.ID() > 0)
+ }
+ wg.Done()
+ }(i)
+ }
+ wg.Wait()
}
--
⑨