/* ProcessQueries.java ** ------------------- ** ** (1) Using the contents of a file whose name is provided via the first ** command-line argument (args[0]), a set of (key,value)-pairs (each ** element of which is in the form of an instance of the ** KeyValPairWithCounts class) is built. This set is in the form of ** an instance of the KeyValPairSet class. ** It is assumed that the first line of the file contains a number ** indicating the maximum number of elements allowed in the set. ** Each subsequent line contains a description of a (key,value)-pair ** in a form suitable to be passed to the constructor of the ** KeyValPairWithCounts class. ** ** (2) The queries in the file whose name is provided via the second ** command-line argument (args[1]) are processed. Each query is ** expected to match one of the keys in the set discussed in (1). ** The program's response to each such query is a line of output ** that identifies the components of the (key,value)-pair with the ** matching key and a measure of how much work the instance of ** KeyValPairSet did in order to retrieve that pair. Afterwards, ** a measure of the total work done in processing all the queries is ** reported. ** ** (3) The same file of queries is processed for a second time. ** However, before doing this second pass, the KeyValPairSet ** object is put into "adjusting" mode, which means that, in ** reaction to each query, it may modify the data structure that ** it maintains for storing the members of the set so that members ** that are frequently the subject of a query can be found more quickly. ** These adjustments are seen to make a significant difference in ** terms of how much work was needed during Pass #2 vs. Pass #1. ** ** (4) The same file of queries is processed for a third time, this time ** with the "adjusting" mode having been turned off. However, by the ** time the third pass has begun, the data structure holding the ** members of the set has been adjusted to the point where the queries ** are carried out using much less work than even during Pass #2. ** ** Authors: P.M.J. & R.W.M. ** last modified: 12/05/2025 */ import java.util.Scanner; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; public class ProcessQueries { public static void main(String args[]) throws IOException { // Build a set of (key,value)-pairs using the data in the // file named by the first command-line argument. KeyValPairSet setOfPairs = new KeyValPairSet(args[0]); // The second command-line argument names the file in which // the queries are to be found. String queryFileName = args[1]; System.out.println("\nPass 1 ..."); doOnePass(setOfPairs, queryFileName); System.out.println("End of Pass 1"); setOfPairs.turnAdjustingOn(); System.out.println("\nPass 2 ..."); doOnePass(setOfPairs, queryFileName); System.out.println("End of Pass 2"); // If a third command-line argument was supplied, a description of // the set is written into the file named by that argument. This file // is suitable to be used by the constructor of KeyValPairSet to // reconstitute the set. if (args.length > 2) { setOfPairs.toFile(args[2]); } setOfPairs.turnAdjustingOff(); System.out.println("\nPass 3 ..."); doOnePass(setOfPairs, queryFileName); System.out.println("End of Pass 3"); System.out.println("\nDone!!!"); } /* Using the processQueries() method, applies to the given set of ** (key,value)-pairs the queries in the file whose name is given. ** Afterwards, statistics relevant to performance are reported. */ private static void doOnePass(KeyValPairSet setOfPairs, String fileName) { System.out.printf("set cardinality: %d; set capacity: %d\n", setOfPairs.getCardinality(), setOfPairs.getCapacity()); setOfPairs.resetComparisonCounts(); int numQueries = processQueries(setOfPairs, fileName); int numComparisons = setOfPairs.getComparisonCount(); double comparisonsPerQuery = (double)numComparisons / numQueries; System.out.printf("\n# of queries: %d; # of comparisons: %d; average: %.2f\n", numQueries, numComparisons, comparisonsPerQuery); } /* Applies to the given set of (key,value)-pairs the queries ** in the file whose name is given. */ public static int processQueries(KeyValPairSet setOfPairs, String fileName) { Scanner input = null; try { // Create a Scanner object that can read from the named file. input = new Scanner(new File(fileName)); } catch (FileNotFoundException e) { // If no file of that name exists, the program aborts. e.printStackTrace(); System.exit(0); } int prev = 0; // # of comparisons made prior to the most recent query int curr; // # of comparisons made including the most recent query int queryCount = 0; while (input.hasNextLine()) { queryCount++; String key = input.nextLine().trim(); String val = setOfPairs.getValue(key); //Print the KeyValPair result of this search System.out.printf("Key:%s; Value: %s",key,val); curr = setOfPairs.getComparisonCount(); // Print (within curly braces) the number of comparisons performed // in processing this query. System.out.println(" {" + (curr - prev) + "}"); prev = curr; } return queryCount; } }