31 import java.nio.file.Paths;
32 import java.util.ArrayList;
33 import java.util.List;
34 import java.util.Optional;
35 import java.util.function.Function;
36 import java.util.stream.Stream;
37
38 /**
39 * Cgroup version agnostic controller logic
40 *
41 */
42 public interface CgroupSubsystemController {
43
44 public static final String EMPTY_STR = "";
45
46 public String path();
47
48 /**
49 * getStringValue
50 *
51 * Return the first line of the file "parm" argument from the controller.
52 *
53 * TODO: Consider using weak references for caching BufferedReader object.
54 *
55 * @param controller
56 * @param parm
57 * @return Returns the contents of the file specified by param.
58 */
59 public static String getStringValue(CgroupSubsystemController controller, String param) {
60 if (controller == null) return null;
61
62 try {
63 return CgroupUtil.readStringValue(controller, param);
64 }
65 catch (IOException e) {
66 return null;
67 }
68
69 }
70
71 public static long getLongValueMatchingLine(CgroupSubsystemController controller,
72 String param,
73 String match,
74 Function<String, Long> conversion) {
75 long retval = Metrics.LONG_RETVAL_UNLIMITED;
76 try {
77 Path filePath = Paths.get(controller.path(), param);
78 List<String> lines = CgroupUtil.readAllLinesPrivileged(filePath);
79 for (String line : lines) {
80 if (line.startsWith(match)) {
81 retval = conversion.apply(line);
82 break;
83 }
84 }
85 } catch (IOException e) {
86 // Ignore. Default is unlimited.
87 }
88 return retval;
89 }
90
91 public static long getLongValue(CgroupSubsystemController controller,
92 String parm,
93 Function<String, Long> conversion) {
94 String strval = getStringValue(controller, parm);
95 return conversion.apply(strval);
96 }
97
98 public static double getDoubleValue(CgroupSubsystemController controller, String parm) {
99 String strval = getStringValue(controller, parm);
100
101 if (strval == null) return 0L;
102
103 double retval = Double.parseDouble(strval);
104
105 return retval;
106 }
107
108 /**
109 * getSubSystemlongEntry
110 *
111 * Return the long value from the line containing the string "entryname"
112 * within file "parm" in the "subsystem".
113 *
114 * TODO: Consider using weak references for caching BufferedReader object.
115 *
116 * @param controller
117 * @param parm
118 * @param entryname
119 * @return long value
120 */
121 public static long getLongEntry(CgroupSubsystemController controller, String parm, String entryname) {
122 if (controller == null) return 0L;
123
124 try (Stream<String> lines = CgroupUtil.readFilePrivileged(Paths.get(controller.path(), parm))) {
125
126 Optional<String> result = lines.map(line -> line.split(" "))
127 .filter(line -> (line.length == 2 &&
128 line[0].equals(entryname)))
129 .map(line -> line[1])
130 .findFirst();
131
132 return result.isPresent() ? Long.parseLong(result.get()) : 0L;
133 }
134 catch (IOException e) {
135 return 0L;
136 }
137 }
138
139 /**
140 * StringRangeToIntArray
141 *
142 * Convert a string in the form of 1,3-4,6 to an array of
143 * integers containing all the numbers in the range.
144 *
145 * @param range
146 * @return int[] containing a sorted list of processors or memory nodes
147 */
148 public static int[] stringRangeToIntArray(String range) {
149 if (range == null || EMPTY_STR.equals(range)) return null;
150
151 ArrayList<Integer> results = new ArrayList<>();
152 String strs[] = range.split(",");
153 for (String str : strs) {
154 if (str.contains("-")) {
155 String lohi[] = str.split("-");
156 // validate format
157 if (lohi.length != 2) {
158 continue;
159 }
160 int lo = Integer.parseInt(lohi[0]);
161 int hi = Integer.parseInt(lohi[1]);
162 for (int i = lo; i <= hi; i++) {
163 results.add(i);
164 }
165 }
166 else {
167 results.add(Integer.parseInt(str));
168 }
169 }
170
171 // sort results
172 results.sort(null);
173
174 // convert ArrayList to primitive int array
175 int[] ints = new int[results.size()];
176 int i = 0;
177 for (Integer n : results) {
178 ints[i++] = n;
179 }
180
181 return ints;
182 }
183
184 public static long convertStringToLong(String strval, long overflowRetval) {
185 long retval = 0;
186 if (strval == null) return 0L;
187
188 try {
189 retval = Long.parseLong(strval);
190 } catch (NumberFormatException e) {
191 // For some properties (e.g. memory.limit_in_bytes) we may overflow
192 // the range of signed long. In this case, return unlimited
193 BigInteger b = new BigInteger(strval);
194 if (b.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {
195 return overflowRetval;
196 }
197 }
198 return retval;
199 }
200
201 }
|
31 import java.nio.file.Paths;
32 import java.util.ArrayList;
33 import java.util.List;
34 import java.util.Optional;
35 import java.util.function.Function;
36 import java.util.stream.Stream;
37
38 /**
39 * Cgroup version agnostic controller logic
40 *
41 */
42 public interface CgroupSubsystemController {
43
44 public static final String EMPTY_STR = "";
45
46 public String path();
47
48 /**
49 * getStringValue
50 *
51 * Return the first line of the file "param" argument from the controller.
52 *
53 * TODO: Consider using weak references for caching BufferedReader object.
54 *
55 * @param controller
56 * @param param
57 * @return Returns the contents of the file specified by param or null if
58 * an error occurs.
59 */
60 public static String getStringValue(CgroupSubsystemController controller, String param) {
61 if (controller == null) return null;
62
63 try {
64 return CgroupUtil.readStringValue(controller, param);
65 }
66 catch (IOException e) {
67 return null;
68 }
69
70 }
71
72 /**
73 * Get an entry from file "param" within the "controller" directory path
74 * which matches string "match". Applies "conversion" to the matching line.
75 *
76 * @param controller
77 * @param param
78 * @param match
79 * @param conversion
80 * @param defaultRetval
81 * @return The long value as derived by applying "conversion" to the matching
82 * line or "defaultRetval" if there was an error or no match found.
83 */
84 public static long getLongValueMatchingLine(CgroupSubsystemController controller,
85 String param,
86 String match,
87 Function<String, Long> conversion,
88 long defaultRetval) {
89 long retval = defaultRetval;
90 if (controller == null) {
91 return retval;
92 }
93 try {
94 Path filePath = Paths.get(controller.path(), param);
95 List<String> lines = CgroupUtil.readAllLinesPrivileged(filePath);
96 for (String line : lines) {
97 if (line.startsWith(match)) {
98 retval = conversion.apply(line);
99 break;
100 }
101 }
102 } catch (IOException e) {
103 // Ignore. Default is unlimited.
104 }
105 return retval;
106 }
107
108 /**
109 * Get a long value from directory "controller" and file "param", by
110 * applying "conversion" to the string value within the file.
111 *
112 * @param controller
113 * @param param
114 * @param conversion
115 * @param defaultRetval
116 * @return The converted long value or "defaultRetval" if there was an
117 * error.
118 */
119 public static long getLongValue(CgroupSubsystemController controller,
120 String param,
121 Function<String, Long> conversion,
122 long defaultRetval) {
123 String strval = getStringValue(controller, param);
124 if (strval == null) return defaultRetval;
125 return conversion.apply(strval);
126 }
127
128 /**
129 * Get a double value from file "param" within "controller".
130 *
131 * @param controller
132 * @param param
133 * @param defaultRetval
134 * @return The double value or "defaultRetval" if there was an error.
135 */
136 public static double getDoubleValue(CgroupSubsystemController controller, String param, double defaultRetval) {
137 String strval = getStringValue(controller, param);
138
139 if (strval == null) return defaultRetval;
140
141 double retval = Double.parseDouble(strval);
142
143 return retval;
144 }
145
146 /**
147 * getLongEntry
148 *
149 * Return the long value from the line containing the string "entryname"
150 * within file "param" in the "controller".
151 *
152 * TODO: Consider using weak references for caching BufferedReader object.
153 *
154 * @param controller
155 * @param param
156 * @param entryname
157 * @return long value or "defaultRetval" if there was an error or no match
158 * was found.
159 */
160 public static long getLongEntry(CgroupSubsystemController controller, String param, String entryname, long defaultRetval) {
161 if (controller == null) return defaultRetval;
162
163 try (Stream<String> lines = CgroupUtil.readFilePrivileged(Paths.get(controller.path(), param))) {
164
165 Optional<String> result = lines.map(line -> line.split(" "))
166 .filter(line -> (line.length == 2 &&
167 line[0].equals(entryname)))
168 .map(line -> line[1])
169 .findFirst();
170
171 return result.isPresent() ? Long.parseLong(result.get()) : defaultRetval;
172 }
173 catch (IOException e) {
174 return defaultRetval;
175 }
176 }
177
178 /**
179 * stringRangeToIntArray
180 *
181 * Convert a string in the form of 1,3-4,6 to an array of
182 * integers containing all the numbers in the range.
183 *
184 * @param range
185 * @return int[] containing a sorted list of numbers as represented by
186 * the string range. Returns null if there was an error or the input
187 * was an empty string.
188 */
189 public static int[] stringRangeToIntArray(String range) {
190 if (range == null || EMPTY_STR.equals(range)) return null;
191
192 ArrayList<Integer> results = new ArrayList<>();
193 String strs[] = range.split(",");
194 for (String str : strs) {
195 if (str.contains("-")) {
196 String lohi[] = str.split("-");
197 // validate format
198 if (lohi.length != 2) {
199 continue;
200 }
201 int lo = Integer.parseInt(lohi[0]);
202 int hi = Integer.parseInt(lohi[1]);
203 for (int i = lo; i <= hi; i++) {
204 results.add(i);
205 }
206 }
207 else {
208 results.add(Integer.parseInt(str));
209 }
210 }
211
212 // sort results
213 results.sort(null);
214
215 // convert ArrayList to primitive int array
216 int[] ints = new int[results.size()];
217 int i = 0;
218 for (Integer n : results) {
219 ints[i++] = n;
220 }
221
222 return ints;
223 }
224
225 /**
226 * Convert a number from its string representation to a long.
227 *
228 * @param strval
229 * @param overflowRetval
230 * @param defaultRetval
231 * @return The converted long value. "overflowRetval" is returned if the
232 * string representation exceeds the range of type long.
233 * "defaultRetval" is returned if another type of error occurred
234 * during conversion.
235 */
236 public static long convertStringToLong(String strval, long overflowRetval, long defaultRetval) {
237 long retval = defaultRetval;
238 if (strval == null) return retval;
239
240 try {
241 retval = Long.parseLong(strval);
242 } catch (NumberFormatException e) {
243 // For some properties (e.g. memory.limit_in_bytes, cgroups v1) we may overflow
244 // the range of signed long. In this case, return overflowRetval
245 BigInteger b = new BigInteger(strval);
246 if (b.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {
247 return overflowRetval;
248 }
249 }
250 return retval;
251 }
252
253 }
|