]>
git.argeo.org Git - gpl/argeo-suite.git/blob - org.argeo.app.api/src/org/argeo/app/api/IdRange.java
1 package org
.argeo
.app
.api
;
3 import java
.util
.HashSet
;
5 import java
.util
.concurrent
.ThreadLocalRandom
;
7 /** A range of numerical IDs (typically numerical uid or gid). */
9 // see https://systemd.io/UIDS-GIDS/#special-distribution-uid-ranges
10 final static long MIN_INCLUDED
= Long
.parseUnsignedLong("66000");
11 final static long MAX_EXCLUDED
= Long
.parseUnsignedLong("4294967294");
13 // We use long as a de facto unsigned int
16 private final long min
;
18 private final long max
;
20 public IdRange(long min
, long max
) {
25 public IdRange(long minPow10
) {
26 this(minPow10
, maxFromMinPow10(minPow10
));
29 public long getMin() {
33 public long getMax() {
38 public int hashCode() {
43 public boolean equals(Object obj
) {
44 if (obj
instanceof IdRange idRange
) {
45 return min
== idRange
.min
&& max
== idRange
.max
;
51 public String
toString() {
52 return "[" + Long
.toUnsignedString(min
) + "," + Long
.toUnsignedString(max
) + "]";
58 public static synchronized Set
<IdRange
> randomRanges10000(int count
, Set
<IdRange
> forbiddenRanges
) {
59 Set
<IdRange
> res
= new HashSet
<>();
61 for (int i
= 0; i
< count
; i
++) {
62 IdRange newRange
= null;
64 newRange
= randomRange10000();
65 } while (overlap(newRange
, res
) || overlap(newRange
, forbiddenRanges
));
71 public static synchronized IdRange
randomRange10000() {
72 // TODO make it more generic
74 long maxPred
= 429496l;
76 long rand
= ThreadLocalRandom
.current().nextLong(minPred
, maxPred
);
77 long min
= rand
* 10000l;
78 return new IdRange(min
);
81 public static boolean overlap(IdRange idRange
, Set
<IdRange
> idRanges
) {
82 for (IdRange other
: idRanges
) {
83 if (overlap(idRange
, other
))
89 public static boolean overlap(IdRange idRange
, IdRange other
) {
91 // https://stackoverflow.com/questions/3269434/whats-the-most-efficient-way-to-test-if-two-ranges-overlap
92 return idRange
.min
<= other
.max
&& other
.min
<= idRange
.max
;
99 private static long maxFromMinPow10(long minPow10
) {
100 if ((minPow10
% 100) != 0) {
101 throw new IllegalArgumentException(minPow10
+ " must at least ends with two zeroes");
104 exp
: for (int i
= exp
+ 1; i
< 10; i
++) {
105 if ((minPow10
% pow10(i
)) != 0)
109 // System.out.println(exp);
111 long max
= minPow10
+ pow10(exp
) - 1;
116 private static long pow10(int exp
) {
120 return 10 * pow10(exp
- 1);
123 public static void main(String
... args
) {
124 System
.out
.println(maxFromMinPow10(100));
125 System
.out
.println(maxFromMinPow10(78500));
126 System
.out
.println(maxFromMinPow10(716850000));
128 // System.out.println(pow10(6));
129 // System.out.println(maxFromMinPow10(12));
130 // System.out.println(maxFromMinPow10(124));
131 // System.out.println(maxFromMinPow10(99814565));