summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2024-02-02 11:20:08 +0100
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2024-02-04 16:55:06 +0100
commit609d798e342c873143cf7ad05e987f3d8f7fbb45 (patch)
treea47532d5ba4acf3f12aad25791ee24ff802af35e /common
parent53f204310ec8362d7084c123e8e16f5bb73dd257 (diff)
Handle resource changes when the resources is already evicted from cache
Also fix a logical flaw in the cache resizer that made it too aggressive. After this I haven't been able to reproduce #11988, but I need to look closer. Closes #11973 Updates #11988
Diffstat (limited to 'common')
-rw-r--r--common/collections/stack.go67
1 files changed, 67 insertions, 0 deletions
diff --git a/common/collections/stack.go b/common/collections/stack.go
new file mode 100644
index 000000000..0f1581626
--- /dev/null
+++ b/common/collections/stack.go
@@ -0,0 +1,67 @@
+// Copyright 2024 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 collections
+
+import "sync"
+
+// Stack is a simple LIFO stack that is safe for concurrent use.
+type Stack[T any] struct {
+ items []T
+ zero T
+ mu sync.RWMutex
+}
+
+func NewStack[T any]() *Stack[T] {
+ return &Stack[T]{}
+}
+
+func (s *Stack[T]) Push(item T) {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ s.items = append(s.items, item)
+}
+
+func (s *Stack[T]) Pop() (T, bool) {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ if len(s.items) == 0 {
+ return s.zero, false
+ }
+ item := s.items[len(s.items)-1]
+ s.items = s.items[:len(s.items)-1]
+ return item, true
+}
+
+func (s *Stack[T]) Peek() (T, bool) {
+ s.mu.RLock()
+ defer s.mu.RUnlock()
+ if len(s.items) == 0 {
+ return s.zero, false
+ }
+ return s.items[len(s.items)-1], true
+}
+
+func (s *Stack[T]) Len() int {
+ s.mu.RLock()
+ defer s.mu.RUnlock()
+ return len(s.items)
+}
+
+func (s *Stack[T]) Drain() []T {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ items := s.items
+ s.items = nil
+ return items
+}