| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package dscache | 5 package dscache |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "bytes" | 8 "bytes" |
| 9 "crypto/sha1" | 9 "crypto/sha1" |
| 10 "encoding/base64" | 10 "encoding/base64" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 // infinite. This is #seconds instead of time.Duration, because memcache | 31 // infinite. This is #seconds instead of time.Duration, because memcache |
| 32 // truncates expiration to the second, which means a sub-second amount w
ould | 32 // truncates expiration to the second, which means a sub-second amount w
ould |
| 33 // actually truncate to an infinite timeout. | 33 // actually truncate to an infinite timeout. |
| 34 CacheTimeSeconds = int64((time.Hour * 24).Seconds()) | 34 CacheTimeSeconds = int64((time.Hour * 24).Seconds()) |
| 35 | 35 |
| 36 // CompressionThreshold is the number of bytes of entity value after whi
ch | 36 // CompressionThreshold is the number of bytes of entity value after whi
ch |
| 37 // compression kicks in. | 37 // compression kicks in. |
| 38 CompressionThreshold = 860 | 38 CompressionThreshold = 860 |
| 39 | 39 |
| 40 // DefaultShards is the default number of key sharding to do. | 40 // DefaultShards is the default number of key sharding to do. |
| 41 » DefaultShards int = 1 | 41 » DefaultShards = 1 |
| 42 | 42 |
| 43 » // DefaultEnable indicates whether or not caching is globally enabled or | 43 » // DefaultEnabled indicates whether or not caching is globally enabled o
r |
| 44 // disabled by default. Can still be overridden by CacheEnableMeta. | 44 // disabled by default. Can still be overridden by CacheEnableMeta. |
| 45 DefaultEnabled = true | 45 DefaultEnabled = true |
| 46 ) | 46 ) |
| 47 | 47 |
| 48 const ( | 48 const ( |
| 49 // MemcacheVersion will be incremented in the event that the in-memcache |
| 50 // representation of the cache data is modified. |
| 49 MemcacheVersion = "1" | 51 MemcacheVersion = "1" |
| 50 | 52 |
| 51 // KeyFormat is the format string used to generate memcache keys. It's | 53 // KeyFormat is the format string used to generate memcache keys. It's |
| 52 // gae:<version>:<shard#>:<base64_std_nopad(sha1(datastore.Key))> | 54 // gae:<version>:<shard#>:<base64_std_nopad(sha1(datastore.Key))> |
| 53 » KeyFormat = "gae:" + MemcacheVersion + ":%x:%s" | 55 » KeyFormat = "gae:" + MemcacheVersion + ":%x:%s" |
| 56 |
| 57 » // Sha1B64Padding is the number of padding characters a base64 encoding
of |
| 58 » // a sha1 has. |
| 54 Sha1B64Padding = 1 | 59 Sha1B64Padding = 1 |
| 55 Sha1B64Size = 28 - Sha1B64Padding | |
| 56 | 60 |
| 57 » MaxShards = 256 | 61 » // MaxShards is the maximum number of shards a single entity can have. |
| 58 » MaxShardsLen = len("ff") | 62 » MaxShards = 256 |
| 63 |
| 64 » // MaxShardsLen is the number of characters in the key the shard field |
| 65 » // occupies. |
| 66 » MaxShardsLen = len("ff") |
| 67 |
| 68 » // InternalGAEPadding is the estimated internal padding size that GAE ta
kes |
| 69 » // per memcache line. |
| 70 » // https://cloud.google.com/appengine/docs/go/memcache/#Go_Limits |
| 59 InternalGAEPadding = 96 | 71 InternalGAEPadding = 96 |
| 60 ValueSizeLimit = (1000 * 1000) - InternalGAEPadding - MaxShardsLen | |
| 61 | 72 |
| 62 » CacheEnableMeta = "dscache.enable" | 73 » // ValueSizeLimit is the maximum encoded size a datastore key+entry may |
| 74 » // occupy. If a datastore entity is too large, it will have an indefinit
e |
| 75 » // lock which will cause all clients to fetch it from the datastore. |
| 76 » ValueSizeLimit = (1000 * 1000) - InternalGAEPadding - MaxShardsLen |
| 77 |
| 78 » // CacheEnableMeta is the gae metadata key name for whether or not dscac
he |
| 79 » // is enabled for an entity type at all. |
| 80 » CacheEnableMeta = "dscache.enable" |
| 81 |
| 82 » // CacheExpirationMeta is the gae metadata key name for the default |
| 83 » // expiration time (in seconds) for an entity type. |
| 63 CacheExpirationMeta = "dscache.expiration" | 84 CacheExpirationMeta = "dscache.expiration" |
| 64 | 85 |
| 65 // NonceUint32s is the number of 32 bit uints to use in the 'lock' nonce
. | 86 // NonceUint32s is the number of 32 bit uints to use in the 'lock' nonce
. |
| 66 NonceUint32s = 2 | 87 NonceUint32s = 2 |
| 67 | 88 |
| 68 // GlobalEnabledCheckInterval is how frequently IsGloballyEnabled should
check | 89 // GlobalEnabledCheckInterval is how frequently IsGloballyEnabled should
check |
| 69 // the globalEnabled datastore entry. | 90 // the globalEnabled datastore entry. |
| 70 GlobalEnabledCheckInterval = 5 * time.Minute | 91 GlobalEnabledCheckInterval = 5 * time.Minute |
| 71 ) | 92 ) |
| 72 | 93 |
| 73 // internalValueSizeLimit is a var for testing purposes. | 94 // internalValueSizeLimit is a var for testing purposes. |
| 74 var internalValueSizeLimit = ValueSizeLimit | 95 var internalValueSizeLimit = ValueSizeLimit |
| 75 | 96 |
| 97 // CompressionType is the type of compression a single memcache entry has. |
| 76 type CompressionType byte | 98 type CompressionType byte |
| 77 | 99 |
| 100 // Types of compression. ZlibCompression uses "compress/zlib". |
| 78 const ( | 101 const ( |
| 79 NoCompression CompressionType = iota | 102 NoCompression CompressionType = iota |
| 80 ZlibCompression | 103 ZlibCompression |
| 81 ) | 104 ) |
| 82 | 105 |
| 83 func (c CompressionType) String() string { | 106 func (c CompressionType) String() string { |
| 84 switch c { | 107 switch c { |
| 85 case NoCompression: | 108 case NoCompression: |
| 86 return "NoCompression" | 109 return "NoCompression" |
| 87 case ZlibCompression: | 110 case ZlibCompression: |
| 88 return "ZlibCompression" | 111 return "ZlibCompression" |
| 89 default: | 112 default: |
| 90 return fmt.Sprintf("UNKNOWN_CompressionType(%d)", c) | 113 return fmt.Sprintf("UNKNOWN_CompressionType(%d)", c) |
| 91 } | 114 } |
| 92 } | 115 } |
| 93 | 116 |
| 94 // FlagValue is used to indicate if a memcache entry currently contains an | 117 // FlagValue is used to indicate if a memcache entry currently contains an |
| 95 // item or a lock. | 118 // item or a lock. |
| 96 type FlagValue uint32 | 119 type FlagValue uint32 |
| 97 | 120 |
| 121 // States for a memcache entry. ItemUNKNOWN exists to distinguish the default |
| 122 // zero state from a valid state, but shouldn't ever be observed in memcache. . |
| 98 const ( | 123 const ( |
| 99 ItemUKNONWN FlagValue = iota | 124 ItemUKNONWN FlagValue = iota |
| 100 ItemHasData | 125 ItemHasData |
| 101 ItemHasLock | 126 ItemHasLock |
| 102 ) | 127 ) |
| 103 | 128 |
| 104 func MakeMemcacheKey(shard int, k datastore.Key) string { | 129 // MakeMemcacheKey generates a memcache key for the given datastore Key. This |
| 130 // is useful for debugging. |
| 131 func MakeMemcacheKey(shard int, k *datastore.Key) string { |
| 105 return fmt.Sprintf(KeyFormat, shard, HashKey(k)) | 132 return fmt.Sprintf(KeyFormat, shard, HashKey(k)) |
| 106 } | 133 } |
| 107 | 134 |
| 108 func HashKey(k datastore.Key) string { | 135 // HashKey generates just the hashed portion of the MemcacheKey. |
| 136 func HashKey(k *datastore.Key) string { |
| 109 dgst := sha1.Sum(serialize.ToBytes(k)) | 137 dgst := sha1.Sum(serialize.ToBytes(k)) |
| 110 buf := bytes.Buffer{} | 138 buf := bytes.Buffer{} |
| 111 enc := base64.NewEncoder(base64.StdEncoding, &buf) | 139 enc := base64.NewEncoder(base64.StdEncoding, &buf) |
| 112 _, _ = enc.Write(dgst[:]) | 140 _, _ = enc.Write(dgst[:]) |
| 113 enc.Close() | 141 enc.Close() |
| 114 return buf.String()[:buf.Len()-Sha1B64Padding] | 142 return buf.String()[:buf.Len()-Sha1B64Padding] |
| 115 } | 143 } |
| OLD | NEW |