/* This file is part of GNU Taler (C) 2022 Taler Systems S.A. GNU Taler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Taler; see the file COPYING. If not, see @author: Boss Marco */ const getRandomInt = function(max: number) { return Math.floor(Math.random() * max); } abstract class BenchMerchantIDGenerator { abstract getRandomMerchantID(): number } class ZipfGenerator extends BenchMerchantIDGenerator { weights: number[]; total_weight: number; constructor(numMerchants: number) { super(); this.weights = new Array(numMerchants); for (var i = 0; i < this.weights.length; i++) { /* we use integers (floor), make sure we have big enough values * by multiplying with * numMerchants again */ this.weights[i] = Math.floor((numMerchants/(i+1)) * numMerchants); } this.total_weight = this.weights.reduce((p, n) => p + n); } getRandomMerchantID(): number { let random = getRandomInt(this.total_weight); let current = 0; for (var i = 0; i < this.weights.length; i++) { current += this.weights[i]; if (random <= current) { return i+1; } } /* should never come here */ return getRandomInt(this.weights.length); } } class RandomGenerator extends BenchMerchantIDGenerator { max: number constructor(numMerchants: number) { super(); this.max = numMerchants } getRandomMerchantID() { return getRandomInt(this.max); } } export default function(type: string, maxID: number): BenchMerchantIDGenerator { switch (type) { case "zipf": return new ZipfGenerator(maxID); case "rand": return new RandomGenerator(maxID); default: throw new Error("Valid types are 'zipf' and 'rand'"); } }