]> git.maquefel.me Git - brevno-suite/hugo/commitdiff
Replace the concurrent map with an identical upstream version
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Sun, 19 Apr 2026 20:14:14 +0000 (22:14 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 20 Apr 2026 16:33:59 +0000 (18:33 +0200)
common/hmaps/map.go [deleted file]
common/hmaps/map_test.go [deleted file]
hugolib/content_map_page_assembler.go
hugolib/hugo_sites.go
internal/warpc/warpc.go
resources/resource_cache.go

diff --git a/common/hmaps/map.go b/common/hmaps/map.go
deleted file mode 100644 (file)
index 8bb1cfa..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2026 The Hugo Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package hmaps
-
-import (
-       "iter"
-       "sync"
-)
-
-func NewMap[K comparable, T any]() *Map[K, T] {
-       return &Map[K, T]{
-               m: make(map[K]T),
-       }
-}
-
-// Map is a thread safe map backed by a Go map.
-type Map[K comparable, T any] struct {
-       m  map[K]T
-       mu sync.RWMutex
-}
-
-// Get gets the value for the given key.
-// It returns the zero value of T if the key is not found.
-func (m *Map[K, T]) Get(key K) T {
-       v, _ := m.Lookup(key)
-       return v
-}
-
-// Lookup looks up the given key in the map.
-// It returns the value and a boolean indicating whether the key was found.
-func (m *Map[K, T]) Lookup(key K) (T, bool) {
-       m.mu.RLock()
-       v, found := m.m[key]
-       m.mu.RUnlock()
-       return v, found
-}
-
-// GetOrCreate gets the value for the given key if it exists, or creates it if not.
-func (m *Map[K, T]) GetOrCreate(key K, create func() (T, error)) (T, error) {
-       v, found := m.Lookup(key)
-       if found {
-               return v, nil
-       }
-       m.mu.Lock()
-       defer m.mu.Unlock()
-       v, found = m.m[key]
-       if found {
-               return v, nil
-       }
-       v, err := create()
-       if err != nil {
-               return v, err
-       }
-       m.m[key] = v
-       return v, nil
-}
-
-// Set sets the given key to the given value.
-func (m *Map[K, T]) Set(key K, value T) {
-       m.mu.Lock()
-       m.m[key] = value
-       m.mu.Unlock()
-}
-
-// Delete deletes the given key from the map.
-// It returns true if the key was found and deleted, false otherwise.
-func (m *Map[K, T]) Delete(key K) bool {
-       m.mu.Lock()
-       defer m.mu.Unlock()
-       if _, found := m.m[key]; found {
-               delete(m.m, key)
-               return true
-       }
-       return false
-}
-
-// WithWriteLock executes the given function with a write lock on the map.
-func (m *Map[K, T]) WithWriteLock(f func(m map[K]T) error) error {
-       m.mu.Lock()
-       defer m.mu.Unlock()
-       return f(m.m)
-}
-
-// SetIfAbsent sets the given key to the given value if the key does not already exist in the map.
-// It returns true if the value was set, false otherwise.
-func (m *Map[K, T]) SetIfAbsent(key K, value T) bool {
-       m.mu.RLock()
-       if _, found := m.m[key]; !found {
-               m.mu.RUnlock()
-               return m.doSetIfAbsent(key, value)
-       }
-       m.mu.RUnlock()
-       return false
-}
-
-func (m *Map[K, T]) doSetIfAbsent(key K, value T) bool {
-       m.mu.Lock()
-       defer m.mu.Unlock()
-       if _, found := m.m[key]; !found {
-               m.m[key] = value
-               return true
-       }
-       return false
-}
-
-// All returns an iterator over all key/value pairs in the map.
-// A read lock is held during the iteration.
-func (m *Map[K, T]) All() iter.Seq2[K, T] {
-       return func(yield func(K, T) bool) {
-               m.mu.RLock()
-               defer m.mu.RUnlock()
-               for k, v := range m.m {
-                       if !yield(k, v) {
-                               return
-                       }
-               }
-       }
-}
diff --git a/common/hmaps/map_test.go b/common/hmaps/map_test.go
deleted file mode 100644 (file)
index 7791bc6..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2026 The Hugo Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package hmaps
-
-import (
-       "testing"
-
-       qt "github.com/frankban/quicktest"
-)
-
-func TestMap(t *testing.T) {
-       c := qt.New(t)
-
-       m := NewMap[string, int]()
-
-       m.Set("b", 42)
-       v, found := m.Lookup("b")
-       c.Assert(found, qt.Equals, true)
-       c.Assert(v, qt.Equals, 42)
-       v = m.Get("b")
-       c.Assert(v, qt.Equals, 42)
-       v, found = m.Lookup("c")
-       c.Assert(found, qt.Equals, false)
-       c.Assert(v, qt.Equals, 0)
-       v = m.Get("c")
-       c.Assert(v, qt.Equals, 0)
-       v, err := m.GetOrCreate("d", func() (int, error) {
-               return 100, nil
-       })
-       c.Assert(err, qt.IsNil)
-       c.Assert(v, qt.Equals, 100)
-       v, found = m.Lookup("d")
-       c.Assert(found, qt.Equals, true)
-       c.Assert(v, qt.Equals, 100)
-
-       v, err = m.GetOrCreate("d", func() (int, error) {
-               return 200, nil
-       })
-       c.Assert(err, qt.IsNil)
-       c.Assert(v, qt.Equals, 100)
-
-       wasSet := m.SetIfAbsent("e", 300)
-       c.Assert(wasSet, qt.Equals, true)
-       v, found = m.Lookup("e")
-       c.Assert(found, qt.Equals, true)
-       c.Assert(v, qt.Equals, 300)
-
-       wasSet = m.SetIfAbsent("e", 400)
-       c.Assert(wasSet, qt.Equals, false)
-       v, found = m.Lookup("e")
-       c.Assert(found, qt.Equals, true)
-       c.Assert(v, qt.Equals, 300)
-
-       m.WithWriteLock(func(m map[string]int) error {
-               m["f"] = 500
-               return nil
-       })
-       v, found = m.Lookup("f")
-       c.Assert(found, qt.Equals, true)
-       c.Assert(v, qt.Equals, 500)
-}
index 3c776922462d2659f69d7d0be85fd53a7ee7b203..3d013668701dc17df0e7cd4e7e4b263245bccaa9 100644 (file)
@@ -21,8 +21,8 @@ import (
        "strings"
        "time"
 
+       "github.com/bep/helpers/maphelpers"
        "github.com/gohugoio/go-radix"
-       "github.com/gohugoio/hugo/common/hmaps"
        "github.com/gohugoio/hugo/common/paths"
        "github.com/gohugoio/hugo/common/types"
        "github.com/gohugoio/hugo/hugofs/files"
@@ -54,9 +54,9 @@ type allPagesAssembler struct {
        rwRoot *doctree.NodeShiftTreeWalker[contentNode] // walks resources.
 
        // Walking state.
-       seenTerms        *hmaps.Map[term, sitesmatrix.Vectors]
-       droppedPages     *hmaps.Map[*Site, []string] // e.g. drafts, expired, future.
-       seenRootSections *hmaps.Map[string, bool]
+       seenTerms        *maphelpers.ConcurrentMap[term, sitesmatrix.Vectors]
+       droppedPages     *maphelpers.ConcurrentMap[*Site, []string] // e.g. drafts, expired, future.
+       seenRootSections *maphelpers.ConcurrentMap[string, bool]
        seenHome         bool // set before we fan out to multiple goroutines.
 }
 
@@ -75,7 +75,7 @@ func newAllPagesAssembler(
        pw := rw.Extend()
        pw.Tree = m.treePages
 
-       seenRootSections := hmaps.NewMap[string, bool]()
+       seenRootSections := maphelpers.NewConcurrentMap[string, bool]()
        seenRootSections.Set("", true) // home.
 
        return &allPagesAssembler{
@@ -83,8 +83,8 @@ func newAllPagesAssembler(
                h:                          h,
                m:                          m,
                assembleChanges:            assembleChanges,
-               seenTerms:                  hmaps.NewMap[term, sitesmatrix.Vectors](),
-               droppedPages:               hmaps.NewMap[*Site, []string](),
+               seenTerms:                  maphelpers.NewConcurrentMap[term, sitesmatrix.Vectors](),
+               droppedPages:               maphelpers.NewConcurrentMap[*Site, []string](),
                seenRootSections:           seenRootSections,
                assembleSectionsInParallel: !h.isRebuild(), // On partial rebuilds, there's potential data races with parallel section assembly.
                pwRoot:                     pw,
index 50ae2f2d92cc433a716ab0223695ac939e5ce684..87c04035dffbe4e9f2c2d3ecd30a817e3e5175f7 100644 (file)
@@ -25,6 +25,7 @@ import (
        "sync/atomic"
        "time"
 
+       "github.com/bep/helpers/maphelpers"
        "github.com/bep/logg"
        "github.com/gohugoio/go-radix"
        "github.com/gohugoio/hugo/cache/dynacache"
@@ -99,8 +100,8 @@ type HugoSites struct {
        translationKeyPages *hmaps.SliceCache[page.Page]
 
        pageTrees                    *pageTrees
-       previousPageTreesWalkContext *doctree.WalkContext[contentNode]     // Set for rebuilds only.
-       previousSeenTerms            *hmaps.Map[term, sitesmatrix.Vectors] // Set for rebuilds only.
+       previousPageTreesWalkContext *doctree.WalkContext[contentNode]                    // Set for rebuilds only.
+       previousSeenTerms            *maphelpers.ConcurrentMap[term, sitesmatrix.Vectors] // Set for rebuilds only.
 
        printUnusedTemplatesInit            sync.Once
        printPathWarningsInit               sync.Once
index 58dcf5dc7d873f7fc3200fd745e68badac9229c4..061c08768aa82b6635d772ae9ed951c1c59eeb5a 100644 (file)
@@ -28,9 +28,9 @@ import (
        "sync/atomic"
        "time"
 
+       "github.com/bep/helpers/maphelpers"
        "github.com/bep/textandbinarywriter"
 
-       "github.com/gohugoio/hugo/common/hmaps"
        "github.com/gohugoio/hugo/common/hstrings"
        "github.com/gohugoio/hugo/common/hugio"
        "golang.org/x/sync/errgroup"
@@ -253,7 +253,7 @@ func (d *dispatcher[Q, R]) newCall(q Message[Q]) (*call[Q, R], error) {
        if err := q.init(); err != nil {
                return nil, err
        }
-       responseKinds := hmaps.NewMap[string, bool]()
+       responseKinds := maphelpers.NewConcurrentMap[string, bool]()
        for _, rk := range q.Header.ResponseKinds {
                responseKinds.Set(rk, true)
        }
@@ -424,7 +424,7 @@ func (d *dispatcher[Q, R]) pendingCall(id uint32) *call[Q, R] {
 type call[Q, R any] struct {
        request       Message[Q]
        response      Message[R]
-       responseKinds *hmaps.Map[string, bool]
+       responseKinds *maphelpers.ConcurrentMap[string, bool]
        err           error
        donec         chan *call[Q, R]
 }
index dbdd829d2bceed4d6d09c808240858a2ec2f51c3..a9c71c6ce51ac48b6feb28e527cfcef2343c2e8a 100644 (file)
@@ -22,7 +22,7 @@ import (
        "strings"
        "sync"
 
-       "github.com/gohugoio/hugo/common/hmaps"
+       "github.com/bep/helpers/maphelpers"
        "github.com/gohugoio/hugo/resources/resource"
 
        "github.com/gohugoio/hugo/cache/dynacache"
@@ -58,7 +58,7 @@ func newResourceCache(rs *Spec, memCache *dynacache.Cache) *ResourceCache {
                        dynacache.OptionsPartition{ClearWhen: dynacache.ClearOnChange, Weight: 40},
                ),
 
-               cacheResourceTransformationPublished: hmaps.NewMap[string, string](),
+               cacheResourceTransformationPublished: maphelpers.NewConcurrentMap[string, string](),
        }
 }
 
@@ -72,7 +72,7 @@ type ResourceCache struct {
        cacheResourceTransformation *dynacache.Partition[string, *resourceAdapterInner]
 
        // Used in rebuilds. Maps the target path to the last published transformation key.
-       cacheResourceTransformationPublished *hmaps.Map[string, string]
+       cacheResourceTransformationPublished *maphelpers.ConcurrentMap[string, string]
 
        fileCache *filecache.Cache
 }