| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 
|  | 2 // Use of this source code is governed by a BSD-style license that can be | 
|  | 3 // found in the LICENSE file. | 
|  | 4 | 
|  | 5 package dscache | 
|  | 6 | 
|  | 7 import ( | 
|  | 8         "bytes" | 
|  | 9         "crypto/sha1" | 
|  | 10         "encoding/base64" | 
|  | 11         "fmt" | 
|  | 12         "time" | 
|  | 13 | 
|  | 14         "github.com/luci/gae/service/datastore" | 
|  | 15 ) | 
|  | 16 | 
|  | 17 var ( | 
|  | 18         // InstanceEnabledStatic allows you to statically (e.g. in an init() fun
     ction) | 
|  | 19         // bypass this filter by setting it to false. This takes effect when the | 
|  | 20         // application calls IsGloballyEnabled. | 
|  | 21         InstanceEnabledStatic = true | 
|  | 22 | 
|  | 23         // LockTimeSeconds is the number of seconds that a "lock" memcache entry
      will | 
|  | 24         // have its expiration set to. It's set to just over half of the fronten
     d | 
|  | 25         // request handler timeout (currently 60 seconds). | 
|  | 26         LockTimeSeconds = 31 | 
|  | 27 | 
|  | 28         // CacheTimeSeconds is the default number of seconds that a cached entit
     y will | 
|  | 29         // be retained (memcache contention notwithstanding). A value of 0 is | 
|  | 30         // infinite. This is #seconds instead of time.Duration, because memcache | 
|  | 31         // truncates expiration to the second, which means a sub-second amount w
     ould | 
|  | 32         // actually truncate to an infinite timeout. | 
|  | 33         CacheTimeSeconds = int64((time.Hour * 24).Seconds()) | 
|  | 34 | 
|  | 35         // CompressionThreshold is the number of bytes of entity value after whi
     ch | 
|  | 36         // compression kicks in. | 
|  | 37         CompressionThreshold = 860 | 
|  | 38 | 
|  | 39         // DefaultShards is the default number of key sharding to do. | 
|  | 40         DefaultShards int = 1 | 
|  | 41 | 
|  | 42         // DefaultEnable indicates whether or not caching is globally enabled or | 
|  | 43         // disabled by default. Can still be overridden by CacheEnableMeta. | 
|  | 44         DefaultEnabled = true | 
|  | 45 ) | 
|  | 46 | 
|  | 47 const ( | 
|  | 48         MemcacheVersion = "1" | 
|  | 49 | 
|  | 50         // KeyFormat is the format string used to generate memcache keys. It's | 
|  | 51         //   gae:<version>:<shard#>:<base64_std_nopad(sha1(datastore.Key))> | 
|  | 52         KeyFormat      = "gae:" + MemcacheVersion + ":%x:%s" | 
|  | 53         Sha1B64Padding = 1 | 
|  | 54         Sha1B64Size    = 28 - Sha1B64Padding | 
|  | 55 | 
|  | 56         MaxShards          = 256 | 
|  | 57         MaxShardsLen       = len("ff") | 
|  | 58         InternalGAEPadding = 96 | 
|  | 59         ValueSizeLimit     = (1000 * 1000) - InternalGAEPadding - MaxShardsLen | 
|  | 60 | 
|  | 61         CacheEnableMeta     = "dscache.enable" | 
|  | 62         CacheExpirationMeta = "dscache.expiration" | 
|  | 63 | 
|  | 64         // NonceUint32s is the number of 32 bit uints to use in the 'lock' nonce
     . | 
|  | 65         NonceUint32s = 2 | 
|  | 66 | 
|  | 67         // GlobalEnabledCheckInterval is how frequently IsGloballyEnabled should
      check | 
|  | 68         // the globalEnabled datastore entry. | 
|  | 69         GlobalEnabledCheckInterval = 5 * time.Minute | 
|  | 70 ) | 
|  | 71 | 
|  | 72 // internalValueSizeLimit is a var for testing purposes. | 
|  | 73 var internalValueSizeLimit = ValueSizeLimit | 
|  | 74 | 
|  | 75 type CompressionType byte | 
|  | 76 | 
|  | 77 const ( | 
|  | 78         NoCompression CompressionType = iota | 
|  | 79         ZlibCompression | 
|  | 80 ) | 
|  | 81 | 
|  | 82 func (c CompressionType) String() string { | 
|  | 83         switch c { | 
|  | 84         case NoCompression: | 
|  | 85                 return "NoCompression" | 
|  | 86         case ZlibCompression: | 
|  | 87                 return "ZlibCompression" | 
|  | 88         default: | 
|  | 89                 return fmt.Sprintf("UNKNOWN_CompressionType(%d)", c) | 
|  | 90         } | 
|  | 91 } | 
|  | 92 | 
|  | 93 // FlagValue is used to indicate if a memcache entry currently contains an | 
|  | 94 // item or a lock. | 
|  | 95 type FlagValue uint32 | 
|  | 96 | 
|  | 97 const ( | 
|  | 98         ItemUKNONWN FlagValue = iota | 
|  | 99         ItemHasData | 
|  | 100         ItemHasLock | 
|  | 101 ) | 
|  | 102 | 
|  | 103 func MakeMemcacheKey(shard int, k datastore.Key) string { | 
|  | 104         return fmt.Sprintf(KeyFormat, shard, HashKey(k)) | 
|  | 105 } | 
|  | 106 | 
|  | 107 func HashKey(k datastore.Key) string { | 
|  | 108         // errs can't happen, since we're using a byte buffer. | 
|  | 109         buf := bytes.Buffer{} | 
|  | 110         _ = datastore.WriteKey(&buf, datastore.WithoutContext, k) | 
|  | 111         dgst := sha1.Sum(buf.Bytes()) | 
|  | 112         buf.Reset() | 
|  | 113         enc := base64.NewEncoder(base64.StdEncoding, &buf) | 
|  | 114         _, _ = enc.Write(dgst[:]) | 
|  | 115         enc.Close() | 
|  | 116         return buf.String()[:buf.Len()-Sha1B64Padding] | 
|  | 117 } | 
| OLD | NEW | 
|---|