aboutsummaryrefslogtreecommitdiffhomepage
path: root/hugolib/content_map_page.go
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <[email protected]>2024-11-06 10:17:34 +0100
committerBjørn Erik Pedersen <[email protected]>2024-11-06 12:17:30 +0100
commit95e2d5beb8cc5937792e1ed15589434987590e39 (patch)
tree5d351ce750742b4780ba004d6a4e64893e890efe /hugolib/content_map_page.go
parent2c3efc81064a6e0bdde3d02629f06ca87a7d2c08 (diff)
downloadhugo-95e2d5beb8cc5937792e1ed15589434987590e39.tar.gz
hugo-95e2d5beb8cc5937792e1ed15589434987590e39.zip
Fix concurrent map read and map write in short page lookups
Regression introduced in Hugo `v0.137.0`. Fixes #13019
Diffstat (limited to 'hugolib/content_map_page.go')
-rw-r--r--hugolib/content_map_page.go76
1 files changed, 37 insertions, 39 deletions
diff --git a/hugolib/content_map_page.go b/hugolib/content_map_page.go
index 5e8646b21..8c9e4a31a 100644
--- a/hugolib/content_map_page.go
+++ b/hugolib/content_map_page.go
@@ -37,7 +37,6 @@ import (
"github.com/gohugoio/hugo/hugolib/doctree"
"github.com/gohugoio/hugo/hugolib/pagesfromdata"
"github.com/gohugoio/hugo/identity"
- "github.com/gohugoio/hugo/lazy"
"github.com/gohugoio/hugo/media"
"github.com/gohugoio/hugo/output"
"github.com/gohugoio/hugo/resources"
@@ -925,59 +924,58 @@ func newPageMap(i int, s *Site, mcache *dynacache.Cache, pageTrees *pageTrees) *
s: s,
}
- m.pageReverseIndex = &contentTreeReverseIndex{
- initFn: func(rm map[any]contentNodeI) {
- add := func(k string, n contentNodeI) {
- existing, found := rm[k]
- if found && existing != ambiguousContentNode {
- rm[k] = ambiguousContentNode
- } else if !found {
- rm[k] = n
- }
+ m.pageReverseIndex = newContentTreeTreverseIndex(func(get func(key any) (contentNodeI, bool), set func(key any, val contentNodeI)) {
+ add := func(k string, n contentNodeI) {
+ existing, found := get(k)
+ if found && existing != ambiguousContentNode {
+ set(k, ambiguousContentNode)
+ } else if !found {
+ set(k, n)
}
+ }
- w := &doctree.NodeShiftTreeWalker[contentNodeI]{
- Tree: m.treePages,
- LockType: doctree.LockTypeRead,
- Handle: func(s string, n contentNodeI, match doctree.DimensionFlag) (bool, error) {
- p := n.(*pageState)
- if p.PathInfo() != nil {
- add(p.PathInfo().BaseNameNoIdentifier(), p)
- }
- return false, nil
- },
- }
+ w := &doctree.NodeShiftTreeWalker[contentNodeI]{
+ Tree: m.treePages,
+ LockType: doctree.LockTypeRead,
+ Handle: func(s string, n contentNodeI, match doctree.DimensionFlag) (bool, error) {
+ p := n.(*pageState)
+ if p.PathInfo() != nil {
+ add(p.PathInfo().BaseNameNoIdentifier(), p)
+ }
+ return false, nil
+ },
+ }
- if err := w.Walk(context.Background()); err != nil {
- panic(err)
- }
- },
- contentTreeReverseIndexMap: &contentTreeReverseIndexMap{},
- }
+ if err := w.Walk(context.Background()); err != nil {
+ panic(err)
+ }
+ })
return m
}
+func newContentTreeTreverseIndex(init func(get func(key any) (contentNodeI, bool), set func(key any, val contentNodeI))) *contentTreeReverseIndex {
+ return &contentTreeReverseIndex{
+ initFn: init,
+ mm: maps.NewCache[any, contentNodeI](),
+ }
+}
+
type contentTreeReverseIndex struct {
- initFn func(rm map[any]contentNodeI)
- *contentTreeReverseIndexMap
+ initFn func(get func(key any) (contentNodeI, bool), set func(key any, val contentNodeI))
+ mm *maps.Cache[any, contentNodeI]
}
func (c *contentTreeReverseIndex) Reset() {
- c.init.ResetWithLock().Unlock()
+ c.mm.Reset()
}
func (c *contentTreeReverseIndex) Get(key any) contentNodeI {
- c.init.Do(func() {
- c.m = make(map[any]contentNodeI)
- c.initFn(c.contentTreeReverseIndexMap.m)
+ v, _ := c.mm.InitAndGet(key, func(get func(key any) (contentNodeI, bool), set func(key any, val contentNodeI)) error {
+ c.initFn(get, set)
+ return nil
})
- return c.m[key]
-}
-
-type contentTreeReverseIndexMap struct {
- init lazy.OnceMore
- m map[any]contentNodeI
+ return v
}
type sitePagesAssembler struct {