mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-04 01:40:07 +00:00
Optimize random string generator to avoid multiple locks & use bitmasking
This commit is contained in:
parent
0564d52985
commit
c279a53ca0
@ -73,7 +73,7 @@ func tokenSecretReferences() []v1.ObjectReference {
|
|||||||
|
|
||||||
// addTokenSecretReference adds a reference to the ServiceAccountToken that will be created
|
// addTokenSecretReference adds a reference to the ServiceAccountToken that will be created
|
||||||
func addTokenSecretReference(refs []v1.ObjectReference) []v1.ObjectReference {
|
func addTokenSecretReference(refs []v1.ObjectReference) []v1.ObjectReference {
|
||||||
return addNamedTokenSecretReference(refs, "default-token-stdpg")
|
return addNamedTokenSecretReference(refs, "default-token-xn8fg")
|
||||||
}
|
}
|
||||||
|
|
||||||
// addNamedTokenSecretReference adds a reference to the named ServiceAccountToken
|
// addNamedTokenSecretReference adds a reference to the named ServiceAccountToken
|
||||||
@ -118,9 +118,9 @@ func opaqueSecret() *v1.Secret {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// createdTokenSecret returns the ServiceAccountToken secret posted when creating a new token secret.
|
// createdTokenSecret returns the ServiceAccountToken secret posted when creating a new token secret.
|
||||||
// Named "default-token-stdpg", since that is the first generated name after rand.Seed(1)
|
// Named "default-token-xn8fg", since that is the first generated name after rand.Seed(1)
|
||||||
func createdTokenSecret(overrideName ...string) *v1.Secret {
|
func createdTokenSecret(overrideName ...string) *v1.Secret {
|
||||||
return namedCreatedTokenSecret("default-token-stdpg")
|
return namedCreatedTokenSecret("default-token-xn8fg")
|
||||||
}
|
}
|
||||||
|
|
||||||
// namedTokenSecret returns the ServiceAccountToken secret posted when creating a new token secret with the given name.
|
// namedTokenSecret returns the ServiceAccountToken secret posted when creating a new token secret with the given name.
|
||||||
@ -264,12 +264,12 @@ func TestTokenCreation(t *testing.T) {
|
|||||||
|
|
||||||
// Attempt 2
|
// Attempt 2
|
||||||
core.NewGetAction(schema.GroupVersionResource{Version: "v1", Resource: "serviceaccounts"}, metav1.NamespaceDefault, "default"),
|
core.NewGetAction(schema.GroupVersionResource{Version: "v1", Resource: "serviceaccounts"}, metav1.NamespaceDefault, "default"),
|
||||||
core.NewCreateAction(schema.GroupVersionResource{Version: "v1", Resource: "secrets"}, metav1.NamespaceDefault, namedCreatedTokenSecret("default-token-jk9rt")),
|
core.NewCreateAction(schema.GroupVersionResource{Version: "v1", Resource: "secrets"}, metav1.NamespaceDefault, namedCreatedTokenSecret("default-token-txhzt")),
|
||||||
|
|
||||||
// Attempt 3
|
// Attempt 3
|
||||||
core.NewGetAction(schema.GroupVersionResource{Version: "v1", Resource: "serviceaccounts"}, metav1.NamespaceDefault, "default"),
|
core.NewGetAction(schema.GroupVersionResource{Version: "v1", Resource: "serviceaccounts"}, metav1.NamespaceDefault, "default"),
|
||||||
core.NewCreateAction(schema.GroupVersionResource{Version: "v1", Resource: "secrets"}, metav1.NamespaceDefault, namedCreatedTokenSecret("default-token-684pg")),
|
core.NewCreateAction(schema.GroupVersionResource{Version: "v1", Resource: "secrets"}, metav1.NamespaceDefault, namedCreatedTokenSecret("default-token-vnmz7")),
|
||||||
core.NewUpdateAction(schema.GroupVersionResource{Version: "v1", Resource: "serviceaccounts"}, metav1.NamespaceDefault, serviceAccount(addNamedTokenSecretReference(emptySecretReferences(), "default-token-684pg"))),
|
core.NewUpdateAction(schema.GroupVersionResource{Version: "v1", Resource: "serviceaccounts"}, metav1.NamespaceDefault, serviceAccount(addNamedTokenSecretReference(emptySecretReferences(), "default-token-vnmz7"))),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"new serviceaccount with no secrets encountering unending create error": {
|
"new serviceaccount with no secrets encountering unending create error": {
|
||||||
@ -293,10 +293,10 @@ func TestTokenCreation(t *testing.T) {
|
|||||||
core.NewCreateAction(schema.GroupVersionResource{Version: "v1", Resource: "secrets"}, metav1.NamespaceDefault, createdTokenSecret()),
|
core.NewCreateAction(schema.GroupVersionResource{Version: "v1", Resource: "secrets"}, metav1.NamespaceDefault, createdTokenSecret()),
|
||||||
// Retry 1
|
// Retry 1
|
||||||
core.NewGetAction(schema.GroupVersionResource{Version: "v1", Resource: "serviceaccounts"}, metav1.NamespaceDefault, "default"),
|
core.NewGetAction(schema.GroupVersionResource{Version: "v1", Resource: "serviceaccounts"}, metav1.NamespaceDefault, "default"),
|
||||||
core.NewCreateAction(schema.GroupVersionResource{Version: "v1", Resource: "secrets"}, metav1.NamespaceDefault, namedCreatedTokenSecret("default-token-jk9rt")),
|
core.NewCreateAction(schema.GroupVersionResource{Version: "v1", Resource: "secrets"}, metav1.NamespaceDefault, namedCreatedTokenSecret("default-token-txhzt")),
|
||||||
// Retry 2
|
// Retry 2
|
||||||
core.NewGetAction(schema.GroupVersionResource{Version: "v1", Resource: "serviceaccounts"}, metav1.NamespaceDefault, "default"),
|
core.NewGetAction(schema.GroupVersionResource{Version: "v1", Resource: "serviceaccounts"}, metav1.NamespaceDefault, "default"),
|
||||||
core.NewCreateAction(schema.GroupVersionResource{Version: "v1", Resource: "secrets"}, metav1.NamespaceDefault, namedCreatedTokenSecret("default-token-684pg")),
|
core.NewCreateAction(schema.GroupVersionResource{Version: "v1", Resource: "secrets"}, metav1.NamespaceDefault, namedCreatedTokenSecret("default-token-vnmz7")),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"new serviceaccount with missing secrets": {
|
"new serviceaccount with missing secrets": {
|
||||||
|
@ -70,16 +70,41 @@ func Perm(n int) []int {
|
|||||||
return rng.rand.Perm(n)
|
return rng.rand.Perm(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We omit vowels from the set of available characters to reduce the chances
|
const (
|
||||||
// of "bad words" being formed.
|
// We omit vowels from the set of available characters to reduce the chances
|
||||||
var alphanums = []rune("bcdfghjklmnpqrstvwxz2456789")
|
// of "bad words" being formed.
|
||||||
|
alphanums = "bcdfghjklmnpqrstvwxz2456789"
|
||||||
|
// No. of bits required to index into alphanums string.
|
||||||
|
alphanumsIdxBits = 5
|
||||||
|
// Mask used to extract last alphanumsIdxBits of an int.
|
||||||
|
alphanumsIdxMask = 1<<alphanumsIdxBits - 1
|
||||||
|
// No. of random letters we can extract from a single int63.
|
||||||
|
maxAlphanumsPerInt = 63 / alphanumsIdxBits
|
||||||
|
)
|
||||||
|
|
||||||
// String generates a random alphanumeric string, without vowels, which is n
|
// String generates a random alphanumeric string, without vowels, which is n
|
||||||
// characters long. This will panic if n is less than zero.
|
// characters long. This will panic if n is less than zero.
|
||||||
func String(length int) string {
|
// How the random string is created:
|
||||||
b := make([]rune, length)
|
// - we generate random int63's
|
||||||
for i := range b {
|
// - from each int63, we are extracting multiple random letters by bit-shifting and masking
|
||||||
b[i] = alphanums[Intn(len(alphanums))]
|
// - if some index is out of range of alphanums we neglect it (unlikely to happen multiple times in a row)
|
||||||
|
func String(n int) string {
|
||||||
|
b := make([]byte, n)
|
||||||
|
rng.Lock()
|
||||||
|
defer rng.Unlock()
|
||||||
|
|
||||||
|
randomInt63 := rng.rand.Int63()
|
||||||
|
remaining := maxAlphanumsPerInt
|
||||||
|
for i := 0; i < n; {
|
||||||
|
if remaining == 0 {
|
||||||
|
randomInt63, remaining = rng.rand.Int63(), maxAlphanumsPerInt
|
||||||
|
}
|
||||||
|
if idx := int(randomInt63 & alphanumsIdxMask); idx < len(alphanums) {
|
||||||
|
b[i] = alphanums[idx]
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
randomInt63 >>= alphanumsIdxBits
|
||||||
|
remaining--
|
||||||
}
|
}
|
||||||
return string(b)
|
return string(b)
|
||||||
}
|
}
|
||||||
@ -87,7 +112,7 @@ func String(length int) string {
|
|||||||
// SafeEncodeString encodes s using the same characters as rand.String. This reduces the chances of bad words and
|
// SafeEncodeString encodes s using the same characters as rand.String. This reduces the chances of bad words and
|
||||||
// ensures that strings generated from hash functions appear consistent throughout the API.
|
// ensures that strings generated from hash functions appear consistent throughout the API.
|
||||||
func SafeEncodeString(s string) string {
|
func SafeEncodeString(s string) string {
|
||||||
r := make([]rune, len(s))
|
r := make([]byte, len(s))
|
||||||
for i, b := range []rune(s) {
|
for i, b := range []rune(s) {
|
||||||
r[i] = alphanums[(int(b) % len(alphanums))]
|
r[i] = alphanums[(int(b) % len(alphanums))]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user