in opennlp-tools/src/main/java/opennlp/tools/stemmer/snowball/SnowballProgram.java [232:311]
protected int find_among(Among[] v) {
int i = 0;
int j = v.length;
int c = cursor;
int l = limit;
int common_i = 0;
int common_j = 0;
boolean first_key_inspected = false;
while (true) {
int k = i + ((j - i) >> 1);
int diff = 0;
int common = common_i < common_j ? common_i : common_j; // smaller
Among w = v[k];
int i2;
for (i2 = common; i2 < w.s.length; i2++) {
if (c + common == l) {
diff = -1;
break;
}
diff = current[c + common] - w.s[i2];
if (diff != 0) {
break;
}
common++;
}
if (diff < 0) {
j = k;
common_j = common;
} else {
i = k;
common_i = common;
}
if (j - i <= 1) {
if (i > 0) {
break; // v->s has been inspected
}
if (j == i) {
break; // only one item in v
}
// - but now we need to go round once more to get
// v->s inspected. This looks messy, but is actually
// the optimal approach.
if (first_key_inspected) {
break;
}
first_key_inspected = true;
}
}
while (true) {
Among w = v[i];
if (common_i >= w.s.length) {
cursor = c + w.s.length;
if (w.method == null) {
return w.result;
}
boolean res = false;
try {
res = (boolean) w.method.invokeExact(this);
} catch (Error | RuntimeException e) {
throw e;
} catch (Throwable e) {
throw new UndeclaredThrowableException(e);
}
cursor = c + w.s.length;
if (res) {
return w.result;
}
}
i = w.substring_i;
if (i < 0) {
return 0;
}
}
}