1 /*
   2  * Permission is hereby granted, free of charge, to any person obtaining a copy of
   3  * this software and associated documentation files (the "Software"), to deal in
   4  * the Software without restriction, including without limitation the rights to
   5  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
   6  * of the Software, and to permit persons to whom the Software is furnished to do
   7  * so, subject to the following conditions:
   8  *
   9  * The above copyright notice and this permission notice shall be included in all
  10  * copies or substantial portions of the Software.
  11  *
  12  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  15  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  18  * SOFTWARE.
  19  */
  20 package jdk.nashorn.internal.runtime.regexp.joni;
  21 
  22 final class MinMaxLen {
  23     int min; /* min byte length */
  24     int max; /* max byte length */
  25 
  26     MinMaxLen() {
  27     }
  28 
  29     MinMaxLen(int min, int max) {
  30         this.min = min;
  31         this.max = max;
  32     }
  33 
  34     /* 1000 / (min-max-dist + 1) */
  35     private static final short distValues[] = {
  36         1000,  500,  333,  250,  200,  167,  143,  125,  111,  100,
  37           91,   83,   77,   71,   67,   63,   59,   56,   53,   50,
  38           48,   45,   43,   42,   40,   38,   37,   36,   34,   33,
  39           32,   31,   30,   29,   29,   28,   27,   26,   26,   25,
  40           24,   24,   23,   23,   22,   22,   21,   21,   20,   20,
  41           20,   19,   19,   19,   18,   18,   18,   17,   17,   17,
  42           16,   16,   16,   16,   15,   15,   15,   15,   14,   14,
  43           14,   14,   14,   14,   13,   13,   13,   13,   13,   13,
  44           12,   12,   12,   12,   12,   12,   11,   11,   11,   11,
  45           11,   11,   11,   11,   11,   10,   10,   10,   10,   10
  46     };
  47 
  48     int distanceValue() {
  49         if (max == INFINITE_DISTANCE) return 0;
  50         int d = max - min;
  51         /* return dist_vals[d] * 16 / (mm->min + 12); */
  52         return d < distValues.length ? distValues[d] : 1;
  53     }
  54 
  55     int compareDistanceValue(MinMaxLen other, int v1, int v2) {
  56         if (v2 <= 0) return -1;
  57         if (v1 <= 0) return 1;
  58 
  59         v1 *= distanceValue();
  60         v2 *= other.distanceValue();
  61 
  62         if (v2 > v1) return 1;
  63         if (v2 < v1) return -1;
  64 
  65         if (other.min < min) return 1;
  66         if (other.min > min) return -1;
  67         return 0;
  68     }
  69 
  70     boolean equal(MinMaxLen other) {
  71         return min == other.min && max == other.max;
  72     }
  73 
  74     void set(int min, int max) {
  75         this.min = min;
  76         this.max = max;
  77     }
  78 
  79     void clear() {
  80         min = max = 0;
  81     }
  82 
  83     void copy(MinMaxLen other) {
  84         min = other.min;
  85         max = other.max;
  86     }
  87 
  88     void add(MinMaxLen other) {
  89         min = distanceAdd(min, other.min);
  90         max = distanceAdd(max, other.max);
  91     }
  92 
  93     void addLength(int len) {
  94         min = distanceAdd(min, len);
  95         max = distanceAdd(max, len);
  96     }
  97 
  98     void altMerge(MinMaxLen other) {
  99         if (min > other.min) min = other.min;
 100         if (max < other.max) max = other.max;
 101     }
 102 
 103     static final int INFINITE_DISTANCE = 0x7FFFFFFF;
 104     static int distanceAdd(int d1, int d2) {
 105         if (d1 == INFINITE_DISTANCE || d2 == INFINITE_DISTANCE) {
 106             return INFINITE_DISTANCE;
 107         } else {
 108             if (d1 <= INFINITE_DISTANCE - d2) return d1 + d2;
 109             else return INFINITE_DISTANCE;
 110         }
 111     }
 112 
 113     static int distanceMultiply(int d, int m) {
 114         if (m == 0) return 0;
 115         if (d < INFINITE_DISTANCE / m) {
 116             return d * m;
 117         } else {
 118             return INFINITE_DISTANCE;
 119         }
 120     }
 121 
 122     static String distanceRangeToString(int a, int b) {
 123         String s = "";
 124         if (a == INFINITE_DISTANCE) {
 125             s += "inf";
 126         } else {
 127             s += "(" + a + ")";
 128         }
 129 
 130         s += "-";
 131 
 132         if (b == INFINITE_DISTANCE) {
 133             s += "inf";
 134         } else {
 135             s += "(" + b + ")";
 136         }
 137         return s;
 138     }
 139 }