Add Node.ID
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 11 Apr 2016 09:49:02 +0000 (11:49 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 11 Apr 2016 09:49:02 +0000 (11:49 +0200)
Fixes #2071

hugolib/node.go
hugolib/node_test.go

index 86ba841c61a2cd37bca42f720fa1d7bf147f6948..7e9ad74587a9fee3b94bcbc0e2ee8d6725eb9a6d 100644 (file)
 package hugolib
 
 import (
-       "github.com/spf13/cast"
        "html/template"
        "sync"
+       "sync/atomic"
        "time"
+
+       "github.com/spf13/cast"
 )
 
 type Node struct {
@@ -37,6 +39,24 @@ type Node struct {
        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 {
index 3b8f868dc3bddc2b9e3c9db4660986e36536df0f..5b83cc0ad5fa64567a9641f5c842cfdb98ae2950 100644 (file)
 package hugolib
 
 import (
+       "sync"
        "testing"
        "time"
+
+       "github.com/stretchr/testify/assert"
 )
 
 func TestNodeSimpleMethods(t *testing.T) {
@@ -38,3 +41,28 @@ func TestNodeSimpleMethods(t *testing.T) {
                }
        }
 }
+
+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()
+}