From: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Date: Mon, 11 Apr 2016 09:49:02 +0000 (+0200)
Subject: Add Node.ID
X-Git-Tag: v0.16~82
X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=5ef52294;p=brevno-suite%2Fhugo

Add Node.ID

Fixes #2071
---

diff --git a/hugolib/node.go b/hugolib/node.go
index 86ba841c..7e9ad745 100644
--- 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 @@ 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 {
diff --git a/hugolib/node_test.go b/hugolib/node_test.go
index 3b8f868d..5b83cc0a 100644
--- 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) {
@@ -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()
+}