cache.go 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // Copyright 2015 go-swagger maintainers
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package spec
  15. import (
  16. "sync"
  17. )
  18. // ResolutionCache a cache for resolving urls
  19. type ResolutionCache interface {
  20. Get(string) (interface{}, bool)
  21. Set(string, interface{})
  22. }
  23. type simpleCache struct {
  24. lock sync.RWMutex
  25. store map[string]interface{}
  26. }
  27. func (s *simpleCache) ShallowClone() ResolutionCache {
  28. store := make(map[string]interface{}, len(s.store))
  29. s.lock.RLock()
  30. for k, v := range s.store {
  31. store[k] = v
  32. }
  33. s.lock.RUnlock()
  34. return &simpleCache{
  35. store: store,
  36. }
  37. }
  38. // Get retrieves a cached URI
  39. func (s *simpleCache) Get(uri string) (interface{}, bool) {
  40. s.lock.RLock()
  41. v, ok := s.store[uri]
  42. s.lock.RUnlock()
  43. return v, ok
  44. }
  45. // Set caches a URI
  46. func (s *simpleCache) Set(uri string, data interface{}) {
  47. s.lock.Lock()
  48. s.store[uri] = data
  49. s.lock.Unlock()
  50. }
  51. var (
  52. // resCache is a package level cache for $ref resolution and expansion.
  53. // It is initialized lazily by methods that have the need for it: no
  54. // memory is allocated unless some expander methods are called.
  55. //
  56. // It is initialized with JSON schema and swagger schema,
  57. // which do not mutate during normal operations.
  58. //
  59. // All subsequent utilizations of this cache are produced from a shallow
  60. // clone of this initial version.
  61. resCache *simpleCache
  62. onceCache sync.Once
  63. _ ResolutionCache = &simpleCache{}
  64. )
  65. // initResolutionCache initializes the URI resolution cache. To be wrapped in a sync.Once.Do call.
  66. func initResolutionCache() {
  67. resCache = defaultResolutionCache()
  68. }
  69. func defaultResolutionCache() *simpleCache {
  70. return &simpleCache{store: map[string]interface{}{
  71. "http://swagger.io/v2/schema.json": MustLoadSwagger20Schema(),
  72. "http://json-schema.org/draft-04/schema": MustLoadJSONSchemaDraft04(),
  73. }}
  74. }
  75. func cacheOrDefault(cache ResolutionCache) ResolutionCache {
  76. onceCache.Do(initResolutionCache)
  77. if cache != nil {
  78. return cache
  79. }
  80. // get a shallow clone of the base cache with swagger and json schema
  81. return resCache.ShallowClone()
  82. }