Created
May 15, 2018 23:33
-
-
Save benley/83a070f2ee418642112f798546b3d39d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local xorshift32(seed) = ( | |
local maxint = (1<<32) - 1; | |
// seed must be non-zero | |
local x = if seed == 0 then 4036811160 else seed; | |
local x1 = x ^ (x << 13); | |
local x2 = x1 ^ (x1 >> 17); | |
local x3 = x2 ^ (x2 << 5); | |
x3 & maxint | |
); | |
{ | |
// A deterministic shuffle function, similar to Fisher-Yates | |
// This will always return the same result for a given input. | |
// | |
// Suitable for shuffling a collection of workloads before partitioning them into shards. | |
// It is *not* suitable for generating crypto seeds or secret keys. | |
// | |
// DO NOT USE THIS FUNCTION IF YOU NEED ACTUAL RANDOMNESS. | |
// Also be warned, this is *slow* in jsonnet. | |
shuffle(items, seed=null):: ( | |
local seed_ = if seed != null then seed else $.hash(std.toString(items)); | |
local rand = xorshift32(seed_); | |
local len = std.length(items); | |
local idx = std.abs(rand) % len; | |
local head = items[:idx]; | |
local tail = items[idx+1:]; | |
if len == 0 then [] else [items[idx]] + $.shuffle(head + tail, rand) tailstrict | |
), | |
hash(s):: std.foldl( | |
function(a, b) (a ^ xorshift32(std.codepoint(b))), | |
std.stringChars(s), 0 | |
), | |
} | |
# example: | |
# local items = std.range(0, 15); | |
# shuffle(items, hash(std.toString(items))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment