JDBC: Idea of a Connection Pool
Problem
Opening a database connection is slow, so real programs keep a pool of ready connections and reuse them. Simulate a pool without a database. The first line is pool N (connections numbered 1 to N). Commands: acquire (give out the free connection with the smallest number and print it, or print none if all are in use), release ID (take the connection back and print ok, or print error if the number is not valid or that connection is not in use), status (print the number of free connections and the number in use, like: 2 1).
Constraints
- 1 <= N <= 100
- 1 <= commands <= 100
Examples
Input
pool 2 acquire acquire acquire release 1 acquire
Output
1 2 none ok 1
Solutions
Keep the free numbers in a structure that gives the smallest one fast (a sorted set or a min-heap). Acquire takes from it and release puts back. A real pool (HikariCP, for example) also checks that a connection is still alive, and waits when none is free.
This problem does not use a database, so all four solutions are really run and verified.
/*
* Problem : Run the commands.
* Input : Input lines.
* Output : Output lines.
* Approach: Sorted free set
* Time : O(n log N)
* Space : O(N)
* Java : 8 or newer.
*/
import java.util.Scanner;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;
public class Main {
// This method solves the task. It receives the input and returns the answer.
static String[] solve(String[] lines) {
int size = Integer.parseInt(lines[0].split(" ")[1]);
// Step 1: A sorted set of the free connection numbers. pollFirst takes the smallest one.
TreeSet<Integer> free = new TreeSet<Integer>();
for (int id = 1; id <= size; id++) {
free.add(id);
}
List<String> out = new ArrayList<String>();
for (int i = 1; i < lines.length; i++) {
String[] part = lines[i].split(" ");
if (part[0].equals("acquire")) {
// Step 2: Acquire removes the smallest free number. An empty set means the pool is exhausted.
Integer id = free.pollFirst();
out.add(id == null ? "none" : String.valueOf(id));
} else if (part[0].equals("release")) {
// Step 3: Only a number in range, which is not already free, can be released.
int id = Integer.parseInt(part[1]);
if (id < 1 || id > size || free.contains(id)) {
out.add("error");
} else {
free.add(id);
out.add("ok");
}
} else {
out.add(free.size() + " " + (size - free.size()));
}
}
return out.toArray(new String[0]);
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
java.util.List<String> all = new java.util.ArrayList<>();
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (!line.isEmpty()) {
all.add(line);
}
}
String[] lines = all.toArray(new String[0]);
System.out.println(String.join("\n", solve(lines)));
}
}
Hints (1)
- Why is a pool faster than opening a connection each time?