0

I am working on a project in which I have two tables in a different database with different schemas. So that means I have two different connection parameters for those two tables to connect using JDBC-

Let's suppose below is the config.property file- in which table1.percentage means 80% of time table1 will be picked and 20% of time table2 will be picked basis on the random number.

TABLES: table1 table2

#For Table1
table1.percentage: 80    

#For Table2
table2.percentage: 20

Below method will read the above config.property file and make a ReadTableConnectionInfo object for each tables.

private static HashMap<String, ReadTableConnectionInfo> tableList = new HashMap<String, ReadTableConnectionInfo>();

private static void readPropertyFile() throws IOException {

    prop.load(Read.class.getClassLoader().getResourceAsStream("config.properties"));

    tableNames = Arrays.asList(prop.getProperty("TABLES").split(" "));

    for (String arg : tableNames) {

        ReadTableConnectionInfo ci = new ReadTableConnectionInfo();

        double percentage = Double.parseDouble(prop.getProperty(arg + ".percentage"));

        ci.setPercentage(percentage);

    tableList.put(arg, ci);
    }
}

Below is the ReadTableConnectionInfo class that will hold all the table connection info for a particular table.

public class ReadTableConnectionInfo {

    public String percentage;

    public double getPercentage() {
        return percentage;
    }

    public void setPercentage(double percentage) {
        this.percentage = percentage;
    }
}

Now in my run method each thread has to generate random number and then decide which table I need to use depending on the percentage for each tables.

private static Random random = new SecureRandom();


@Override
public run() {
  ...


  while ( < 60 minutes) {
    double randomNumber = random.nextDouble() * 100.0;
    ReadTableConnectionInfo tableInfo = selectRandomConnection(randomNumber);

    // do query...
  }
}


//Any problem with the below method?
private ReadTableConnectionInfo selectRandomConnection(double randomNumber) {
  double limit = 0;
  for (ReadTableConnectionInfo ci : tableLists.values()) {
    limit += ci.getPercentage();
    if (randomNumber < limit) {
      return ci;
    }
      }
    throw new IllegalStateException();
   }

Problem Statement:-

Is there any problem in my selectRandomConnection method? Because each thread is working for 60 minutes and in that 60 minutes every time it is only picking table1.

What I am looking for is 80% of time it should pick table1 and 20% of time it should pick table2.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
AKIWEB
  • 19,008
  • 67
  • 180
  • 294
  • The fact that it is selecting tables is irrelevant. What you want to do is a select a random element from a set of elements, but the probability of any element getting selected is not 1/size-of-set but some other number. Now, please explain why you think `selectRandomConnection` should do this, perhaps using a dry-run – Miserable Variable Feb 28 '13 at 22:47
  • See http://stackoverflow.com/questions/1761626/weighted-random-numbers and other questions on the sidebar there, search for weighted/biased random number generator. – Miserable Variable Feb 28 '13 at 22:50
  • Have you debugged? Have you verified the randomNumbers are what you expect? – Aaron Kurtzhals Feb 28 '13 at 22:54
  • My mistake, I messed up somehow in my actual code. I figured that out. Thanks guys for the time. – AKIWEB Mar 01 '13 at 00:39

1 Answers1

1

If you want A to be selected 80% of the time, and B to be selected 20% of the time, on average, just pick a random number between 0 (inclusive) and 100 (exclusive). If the number is < 80, choose A, else choose B.

As simple as that.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255