File: Utilities.java

package info (click to toggle)
beagle 250227-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 9,364 kB
  • sloc: java: 17,684; sh: 55; makefile: 11
file content (372 lines) | stat: -rw-r--r-- 13,046 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
/*
 * Copyright (C) 2014-2021 Brian L. Browning
 *
 * This file is part of Beagle
 *
 * Beagle 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 of the License, or
 * (at your option) any later version.
 *
 * Beagle 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package blbutil;

import java.io.File;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Random;
import java.util.Set;

/**
 * Class {@code Utilities} contains miscellaneous static utility methods.
 *
 * @author Brian L. Browning {@code <browning@uw.edu>}
 */
public class Utilities {

    private Utilities() {
        // private constructor to prevent instantiation
    }

   /**
    * Returns a string representation of the command line arguments.
    * The exact details of the representation are unspecified and
    * subject to change.
    *
    * @param program the name of the program's jar file.
    * @param args command line arguments.
    * @return a string representation of the command line arguments.
    */
    public static String commandLine(String program, String[] args) {
        StringBuilder sb = new StringBuilder(args.length*20);
        long maxMemory = Runtime.getRuntime().maxMemory();
        sb.append(Const.nl);
        sb.append("Command line: java");
        if (maxMemory!=Long.MAX_VALUE) {
            long maxMb = maxMemory / (1024*1024);
            sb.append(" -Xmx");
            sb.append(maxMb);
            sb.append("m");
        }
        sb.append(" -jar ");
        sb.append(program);
        sb.append(Const.nl);
        for (int j = 0; j < args.length; ++j) {
            sb.append("  ");
            sb.append(args[j]);
            sb.append(Const.nl);
        }
        return sb.toString();
    }

    /**
     * Prints a summary of memory use at the time of method invocation
     * to standard output.
     * @param msg a string a message to be printed with the summary
     * of memory use
     */
    public static void printMemoryUse(String msg) {
        long Mb = 1024*1024;
        Runtime rt = Runtime.getRuntime();
        System.out.println(Const.nl + msg
                + Const.tab + "maxMb=" + (rt.maxMemory()/Mb)
                + Const.tab + "totalMb=" + (rt.totalMemory()/Mb)
                + Const.tab + "freeMb=" + (rt.freeMemory()/Mb)
                + Const.tab + "usedMb=" + ((rt.totalMemory() - rt.freeMemory())/Mb));
    }

    /**
     * Returns the current local time as a string.  The
     * exact details of the string representation
     * are unspecified and subject to change.
     *
     * @return the current local time as a string.
     */
    public static String timeStamp() {
        Date now = new Date();
        SimpleDateFormat sdf =
                new SimpleDateFormat("hh:mm a z 'on' dd MMM yyyy");
        return sdf.format(now);
    }

    /**
     * Returns the current minutes and seconds as a string.  The
     * exact details of the string representation
     * are unspecified and subject to change.
     *
     * @return the current local time as a string.
     */
    public static String minutesAndSeconds() {
        Date now = new Date();
        SimpleDateFormat sdf =
                new SimpleDateFormat("mm:ss");
        return sdf.format(now);
    }

    /**
     * <p>Returns a set of identifiers found in a text file that has
     * one identifier per line.  The empty set is returned if
     * {@code file == null}. Blank lines are ignored, and white-space that
     * begins or ends a line is ignored.
     * </p>
     * If an {@code IOException} is thrown, an error message is printed
     * to standard error and the Java virtual machine is forced to terminate.
     *
     * @param file a text file with one identifier per line
     * @return a set of identifiers
     *
     * @throws IllegalArgumentException if the specified file does not exist
     * @throws IllegalArgumentException if the specified file is a directory
     * @throws IllegalArgumentException if any line of the specified
     * file contains two non-white-space characters separated by one or
     * more white-space characters
     */
    public static Set<String> idSet(File file) {
        if (file==null) {
            return Collections.emptySet();
        }
        else {
            if (file.exists()==false) {
                String s = "file does not exist: " + file;
                throw new IllegalArgumentException(s);
            }
            if (file.isDirectory()) {
                String s = "file is a directory: " + file;
                throw new IllegalArgumentException(s);
            }
            Set<String> idSet = new HashSet<>();
            try (FileIt<String> it = InputIt.fromGzipFile(file)) {
                while (it.hasNext()) {
                    String line = it.next().trim();
                    if (line.length() > 0) {
                        if (StringUtil.countFields(line) > 1) {
                            String s = "Line has more than one white-space delimited field (file: '"
                                    + file + "'; line: '" + line + "')";
                            throw new IllegalArgumentException(s);
                        }
                        idSet.add(line);
                    }
                }
            }
            return idSet;
        }
    }

    /**
     * Prints the specified string to the specified {@code PrintWriter} and
     * to standard out.  The line separator string is not appended to the
     * specified string before printing.
     *
     * @param out a print writer
     * @param s a string to be printed
     *
     * @throws NullPointerException if {@code out == null}
     */
    public static void duoPrint(PrintWriter out, CharSequence s) {
        System.out.print(s);
        out.print(s);
    }

   /**
     * Prints the specified string to the specified {@code PrintWriter} and
     * to standard out.  The line separator string is appended to the
     * specified string before printing.
     *
     * @param out a print writer
     * @param s a string to be printed
     *
     * @throws NullPointerException if {@code out == null}
     */
    public static void duoPrintln(PrintWriter out, CharSequence s) {
        System.out.println(s);
        out.println(s);
    }

     /**
     * Returns a string representation of the specified elapsed time
     * in the format "H hours M minutes S seconds".
     *
     * @param nanoseconds the elapsed time in nanoseconds
     *
     * @return a string representation of the specified elapsed time
     */
    public static String elapsedNanos(long nanoseconds) {
        long seconds = Math.round(nanoseconds /1000000000.0);
        StringBuilder sb = new StringBuilder(80);
        if (seconds >= 3600) {
            long hours = seconds / 3600;
            sb.append(hours);
            sb.append(hours==1 ? " hour " : " hours ");
            seconds %= 3600;

        }
        if (seconds >= 60) {
            long minutes = seconds / 60;
            sb.append(minutes);
            sb.append(minutes==1 ? " minute " : " minutes ");
            seconds %= 60;
        }
        sb.append(seconds);
        sb.append(seconds==1 ? " second" : " seconds");
        return sb.toString();
    }

    /**
     * Prints the specified exception, its stack trace, and
     * the specified string to standard error and then terminates the
     * Java virtual machine.
     *
     * @param str a string to be printed to standard error
     * @param thr an exception or error to be printed to standard error
     *
     * @throws NullPointerException if {@code t == null}
     */
    public static void exit(Throwable thr, String str) {
        System.err.println();
        System.err.println(str);
        System.err.println();
        thr.printStackTrace(System.err);
        exit();
    }

    /**
     * Prints the specified exception, its stack trace and then terminates the
     * Java virtual machine.
     *
     * @param t an exception or error to be printed to standard error
     *
     * @throws NullPointerException if {@code e == null}
     */
    public static void exit(Throwable t) {
        t.printStackTrace(System.err);
        exit();
    }

    /**
     * Prints the specified string to standard error and then terminates the
     * Java virtual machine.
     *
     * @param s a string to be written to standard error
     */
    public static void exit(String s) {
        System.err.println();
        System.err.println(s);
        exit();
    }

    /**
     * Prints "Terminating program." to standard error and terminates
     * the Java virtual machine.
     */
    public static void exit() {
        System.err.println();
        System.err.println("Terminating program.");
        System.err.flush();
        System.exit(1);
    }

    /**
     * Randomly shuffles the elements of the specified array.
     * @param ia an array to be shuffled
     * @param random a random number generator
     * @throws NullPointerException if {@code ia == null || random == null}
     */
    public static void shuffle(int[] ia, Random random) {
        for (int j=0; j<ia.length; ++j) {
            int x = random.nextInt(ia.length-j);
            int tmp = ia[j];
            ia[j] = ia[j+x];
            ia[j+x] = tmp;
        }
    }

    /**
     * Shuffles the specified array so that a random set of ${code nElements}
     * elements from the array are the first ${code nElements} elements.
     * The specified array is unchanged if {@code nElements <= 0}.
     * @param ia an array to be shuffled
     * @param nElements the size of the random set of elements which
     * are shuffled to the beginning of the array
     * @param random a random number generator
     * @throws IndexOutOfBoundsException if {@code nElements > ia.length}
     * @throws NullPointerException if {@code ia == null || random == null}
     */
    public static void shuffle(int[] ia, int nElements, Random random) {
        for (int j=0; j<nElements; ++j) {
            int x = random.nextInt(ia.length-j);
            int tmp = ia[j];
            ia[j] = ia[j+x];
            ia[j+x] = tmp;
        }
    }

    /**
     * Returns a two-dimensional array with indices of common array
     * elements. If there are {@code n} elements in common between
     * the {@code a1} and {@code a2} arrays, then for {@code j} satisfying
     * {@code (0 <= j && j < n)}, the {@code [0][j]} and {@code P[1][j]}
     * elements of the returned array are the indices of the {@code j}-th
     * common element in the {@code a1} and {@code a2} arrays respectively.
     * Common elements are indexed according to their order in the
     * {@code a1} array.
     * @param <E> the type of array element
     * @param a1 an array of elements
     * @param a2 an array of elements
     * @return a two-dimensional array with indicies of common array
     * elements
     * @throws IllegalArgumentException if the {@code a1} or {@code a2} arrays
     * have a duplicate element
     * @throws NullPointerException if {@code a1 == null || a2 == null}
     */
    public static <E> int[][] commonIndices(E[] a1, E[] a2) {
        Map<E, Integer> map1 = arrayToMap(a1);
        Map<E, Integer> map2 = arrayToMap(a2);
        map1.keySet().retainAll(map2.keySet());
        int[][] indices = new int[2][map1.size()];
        int index = 0;
        for (int j=0; j<a1.length; ++j) {
            E id = a1[j];
            if (map1.containsKey(id)) {
                assert map2.keySet().contains(id);
                indices[0][index] = map1.get(id);
                indices[1][index++] = map2.get(id);
            }
        }
        return indices;
    }

    /**
     * Returns a map from array element to array index
     * @param <E> the type of array element
     * @param array an array
     * @return a map from array element to array index
     * @throws IllegalArgumentException if the {@code array}
     * has a duplicate element
     * @throws NullPointerException if {@code array == null}
     */
    public static <E> HashMap<E, Integer> arrayToMap(E[] array) {
        HashMap<E, Integer> map = new HashMap<>();
        for (int j=0; j<array.length; ++j) {
            E e = array[j];
            if (map.containsKey(e)) {
                String s = "duplicate element in array: " + e;
                throw new IllegalArgumentException(s);
            }
            map.put(e, j);
        }
        return map;
    }
}