From 5ef52294f90c51697bd3f918b3c3ed83baff657a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Mon, 11 Apr 2016 11:49:02 +0200 Subject: [PATCH] Add Node.ID Fixes #2071 --- hugolib/node.go | 22 +++++++++++++++++++++- hugolib/node_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/hugolib/node.go b/hugolib/node.go index 86ba841c6..7e9ad7458 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 3b8f868dc..5b83cc0ad 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() +}