Skip to content

Instantly share code, notes, and snippets.

@benley
Created May 15, 2018 23:33
Show Gist options
  • Save benley/83a070f2ee418642112f798546b3d39d to your computer and use it in GitHub Desktop.
Save benley/83a070f2ee418642112f798546b3d39d to your computer and use it in GitHub Desktop.
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