diff --git a/cache/partitioned_lazy_cache.go b/cache/partitioned_lazy_cache.go deleted file mode 100644 index 31e66e127..000000000 --- a/cache/partitioned_lazy_cache.go +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2017-present 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 cache - -import ( - "sync" -) - -// Partition represents a cache partition where Load is the callback -// for when the partition is needed. -type Partition struct { - Key string - Load func() (map[string]interface{}, error) -} - -// Lazy represents a lazily loaded cache. -type Lazy struct { - initSync sync.Once - initErr error - cache map[string]interface{} - load func() (map[string]interface{}, error) -} - -// NewLazy creates a lazy cache with the given load func. -func NewLazy(load func() (map[string]interface{}, error)) *Lazy { - return &Lazy{load: load} -} - -func (l *Lazy) init() error { - l.initSync.Do(func() { - c, err := l.load() - l.cache = c - l.initErr = err - - }) - - return l.initErr -} - -// Get initializes the cache if not already initialized, then looks up the -// given key. -func (l *Lazy) Get(key string) (interface{}, bool, error) { - l.init() - if l.initErr != nil { - return nil, false, l.initErr - } - v, found := l.cache[key] - return v, found, nil -} - -// PartitionedLazyCache is a lazily loaded cache paritioned by a supplied string key. -type PartitionedLazyCache struct { - partitions map[string]*Lazy -} - -// NewPartitionedLazyCache creates a new NewPartitionedLazyCache with the supplied -// partitions. -func NewPartitionedLazyCache(partitions ...Partition) *PartitionedLazyCache { - lazyPartitions := make(map[string]*Lazy, len(partitions)) - for _, partition := range partitions { - lazyPartitions[partition.Key] = NewLazy(partition.Load) - } - cache := &PartitionedLazyCache{partitions: lazyPartitions} - - return cache -} - -// Get initializes the partition if not already done so, then looks up the given -// key in the given partition, returns nil if no value found. -func (c *PartitionedLazyCache) Get(partition, key string) (interface{}, error) { - p, found := c.partitions[partition] - - if !found { - return nil, nil - } - - v, found, err := p.Get(key) - if err != nil { - return nil, err - } - - if found { - return v, nil - } - - return nil, nil - -} diff --git a/cache/partitioned_lazy_cache_test.go b/cache/partitioned_lazy_cache_test.go deleted file mode 100644 index 2c61a6560..000000000 --- a/cache/partitioned_lazy_cache_test.go +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright 2017-present 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 cache - -import ( - "errors" - "sync" - "testing" - - qt "github.com/frankban/quicktest" -) - -func TestNewPartitionedLazyCache(t *testing.T) { - t.Parallel() - - c := qt.New(t) - - p1 := Partition{ - Key: "p1", - Load: func() (map[string]interface{}, error) { - return map[string]interface{}{ - "p1_1": "p1v1", - "p1_2": "p1v2", - "p1_nil": nil, - }, nil - }, - } - - p2 := Partition{ - Key: "p2", - Load: func() (map[string]interface{}, error) { - return map[string]interface{}{ - "p2_1": "p2v1", - "p2_2": "p2v2", - "p2_3": "p2v3", - }, nil - }, - } - - cache := NewPartitionedLazyCache(p1, p2) - - v, err := cache.Get("p1", "p1_1") - c.Assert(err, qt.IsNil) - c.Assert(v, qt.Equals, "p1v1") - - v, err = cache.Get("p1", "p2_1") - c.Assert(err, qt.IsNil) - c.Assert(v, qt.IsNil) - - v, err = cache.Get("p1", "p1_nil") - c.Assert(err, qt.IsNil) - c.Assert(v, qt.IsNil) - - v, err = cache.Get("p2", "p2_3") - c.Assert(err, qt.IsNil) - c.Assert(v, qt.Equals, "p2v3") - - v, err = cache.Get("doesnotexist", "p1_1") - c.Assert(err, qt.IsNil) - c.Assert(v, qt.IsNil) - - v, err = cache.Get("p1", "doesnotexist") - c.Assert(err, qt.IsNil) - c.Assert(v, qt.IsNil) - - errorP := Partition{ - Key: "p3", - Load: func() (map[string]interface{}, error) { - return nil, errors.New("Failed") - }, - } - - cache = NewPartitionedLazyCache(errorP) - - v, err = cache.Get("p1", "doesnotexist") - c.Assert(err, qt.IsNil) - c.Assert(v, qt.IsNil) - - _, err = cache.Get("p3", "doesnotexist") - c.Assert(err, qt.Not(qt.IsNil)) - -} - -func TestConcurrentPartitionedLazyCache(t *testing.T) { - t.Parallel() - - c := qt.New(t) - - var wg sync.WaitGroup - - p1 := Partition{ - Key: "p1", - Load: func() (map[string]interface{}, error) { - return map[string]interface{}{ - "p1_1": "p1v1", - "p1_2": "p1v2", - "p1_nil": nil, - }, nil - }, - } - - p2 := Partition{ - Key: "p2", - Load: func() (map[string]interface{}, error) { - return map[string]interface{}{ - "p2_1": "p2v1", - "p2_2": "p2v2", - "p2_3": "p2v3", - }, nil - }, - } - - cache := NewPartitionedLazyCache(p1, p2) - - for i := 0; i < 100; i++ { - wg.Add(1) - go func() { - defer wg.Done() - for j := 0; j < 10; j++ { - v, err := cache.Get("p1", "p1_1") - c.Assert(err, qt.IsNil) - c.Assert(v, qt.Equals, "p1v1") - } - }() - } - wg.Wait() -}