github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/store/cache/cache.go (about)

     1  // Licensed under the Apache License, Version 2.0 (the "License");
     2  // you may not use this file except in compliance with the License.
     3  // You may obtain a copy of the License at
     4  //
     5  //     https://www.apache.org/licenses/LICENSE-2.0
     6  //
     7  // Unless required by applicable law or agreed to in writing, software
     8  // distributed under the License is distributed on an "AS IS" BASIS,
     9  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    10  // See the License for the specific language governing permissions and
    11  // limitations under the License.
    12  //
    13  // Original source: github.com/micro/go-micro/v3/store/cache/cache.go
    14  
    15  package cache
    16  
    17  import (
    18  	"github.com/tickoalcantara12/micro/v3/service/store"
    19  	"github.com/tickoalcantara12/micro/v3/service/store/memory"
    20  )
    21  
    22  // cache store is a store with caching to reduce IO where applicable.
    23  // A memory store is used to cache reads from the given backing store.
    24  // Reads are read through, writes are write-through
    25  type cache struct {
    26  	m       store.Store // the memory store
    27  	b       store.Store // the backing store, could be file, cockroach etc
    28  	options store.Options
    29  }
    30  
    31  // NewStore returns a new cache store
    32  func NewStore(store store.Store, opts ...store.Option) store.Store {
    33  	cf := &cache{
    34  		m: memory.NewStore(opts...),
    35  		b: store,
    36  	}
    37  	return cf
    38  
    39  }
    40  
    41  func (c *cache) init(opts ...store.Option) error {
    42  	for _, o := range opts {
    43  		o(&c.options)
    44  	}
    45  	return nil
    46  }
    47  
    48  // Init initialises the underlying stores
    49  func (c *cache) Init(opts ...store.Option) error {
    50  	if err := c.init(opts...); err != nil {
    51  		return err
    52  	}
    53  	if err := c.m.Init(opts...); err != nil {
    54  		return err
    55  	}
    56  	return c.b.Init(opts...)
    57  }
    58  
    59  // Options allows you to view the current options.
    60  func (c *cache) Options() store.Options {
    61  	return c.options
    62  }
    63  
    64  // Read takes a single key name and optional ReadOptions. It returns matching []*Record or an error.
    65  func (c *cache) Read(key string, opts ...store.ReadOption) ([]*store.Record, error) {
    66  	recs, err := c.m.Read(key, opts...)
    67  	if err != nil && err != store.ErrNotFound {
    68  		return nil, err
    69  	}
    70  	if len(recs) > 0 {
    71  		return recs, nil
    72  	}
    73  	recs, err = c.b.Read(key, opts...)
    74  	if err == nil {
    75  		for _, rec := range recs {
    76  			if err := c.m.Write(rec); err != nil {
    77  				return nil, err
    78  			}
    79  		}
    80  	}
    81  	return recs, err
    82  }
    83  
    84  // Write() writes a record to the store, and returns an error if the record was not written.
    85  // If the write succeeds in writing to memory but fails to write through to file, you'll receive an error
    86  // but the value may still reside in memory so appropriate action should be taken.
    87  func (c *cache) Write(r *store.Record, opts ...store.WriteOption) error {
    88  	if err := c.m.Write(r, opts...); err != nil {
    89  		return err
    90  	}
    91  	return c.b.Write(r, opts...)
    92  }
    93  
    94  // Delete removes the record with the corresponding key from the store.
    95  // If the delete succeeds in writing to memory but fails to write through to file, you'll receive an error
    96  // but the value may still reside in memory so appropriate action should be taken.
    97  func (c *cache) Delete(key string, opts ...store.DeleteOption) error {
    98  	if err := c.m.Delete(key, opts...); err != nil {
    99  		return err
   100  	}
   101  	return c.b.Delete(key, opts...)
   102  }
   103  
   104  // List returns any keys that match, or an empty list with no error if none matched.
   105  func (c *cache) List(opts ...store.ListOption) ([]string, error) {
   106  	keys, err := c.m.List(opts...)
   107  	if err != nil && err != store.ErrNotFound {
   108  		return nil, err
   109  	}
   110  	if len(keys) > 0 {
   111  		return keys, nil
   112  	}
   113  	keys, err = c.b.List(opts...)
   114  	if err == nil {
   115  		for _, key := range keys {
   116  			recs, err := c.b.Read(key)
   117  			if err != nil {
   118  				return nil, err
   119  			}
   120  			for _, r := range recs {
   121  				if err := c.m.Write(r); err != nil {
   122  					return nil, err
   123  				}
   124  			}
   125  
   126  		}
   127  	}
   128  	return keys, err
   129  }
   130  
   131  // Close the store and the underlying store
   132  func (c *cache) Close() error {
   133  	if err := c.m.Close(); err != nil {
   134  		return err
   135  	}
   136  	return c.b.Close()
   137  }
   138  
   139  // String returns the name of the implementation.
   140  func (c *cache) String() string {
   141  	return "cache"
   142  }