1
1
mirror of https://github.com/MarginaliaSearch/MarginaliaSearch.git synced 2025-10-06 07:32:38 +02:00
Files
MarginaliaSearch/code/libraries/array/java/nu/marginalia/array/algo/LongArraySearch.java

161 lines
4.2 KiB
Java
Raw Normal View History

2023-03-04 13:19:01 +01:00
package nu.marginalia.array.algo;
import nu.marginalia.array.page.LongQueryBuffer;
public interface LongArraySearch extends LongArrayBase {
default long binarySearch(long key, long fromIndex, long toIndex) {
long low = 0;
long high = (toIndex - fromIndex) - 1;
long len = high - low;
while (len > 0) {
var half = len / 2;
if (get(fromIndex + low + half) < key) {
low += len - half;
}
len = half;
}
return fromIndex + low;
}
default long binarySearchN(int sz, long key, long fromIndex, long toIndex) {
long low = 0;
long high = (toIndex - fromIndex)/sz - 1;
long len = high - low;
while (len > 0) {
var half = len / 2;
if (get(fromIndex + sz * (low + half)) < key) {
low += len - half;
}
len = half;
}
return fromIndex + sz * low;
}
default void retain(LongQueryBuffer buffer, long boundary, long searchStart, long searchEnd) {
if (searchStart >= searchEnd) return;
long bv = buffer.currentValue();
long av = get(searchStart);
long pos = searchStart;
while (bv <= boundary && buffer.hasMore()) {
if (bv < av) {
if (!buffer.rejectAndAdvance()) break;
bv = buffer.currentValue();
continue;
}
else if (bv == av) {
if (!buffer.retainAndAdvance()) break;
bv = buffer.currentValue();
continue;
}
if (++pos < searchEnd) {
av = get(pos);
}
else {
break;
}
}
}
default void retainN(LongQueryBuffer buffer, int sz, long boundary, long searchStart, long searchEnd) {
if (searchStart >= searchEnd) return;
long bv = buffer.currentValue();
long av = get(searchStart);
long pos = searchStart;
while (bv <= boundary && buffer.hasMore()) {
if (bv < av) {
if (!buffer.rejectAndAdvance()) break;
bv = buffer.currentValue();
continue;
}
else if (bv == av) {
if (!buffer.retainAndAdvance()) break;
bv = buffer.currentValue();
continue;
}
pos += sz;
if (pos < searchEnd) {
av = get(pos);
}
else {
break;
}
}
}
default void reject(LongQueryBuffer buffer, long boundary, long searchStart, long searchEnd) {
if (searchStart >= searchEnd) return;
long bv = buffer.currentValue();
long av = get(searchStart);
long pos = searchStart;
while (bv <= boundary && buffer.hasMore()) {
if (bv < av) {
if (!buffer.retainAndAdvance()) break;
bv = buffer.currentValue();
continue;
}
else if (bv == av) {
if (!buffer.rejectAndAdvance()) break;
bv = buffer.currentValue();
continue;
}
if (++pos < searchEnd) {
av = get(pos);
}
else {
break;
}
}
}
default void rejectN(LongQueryBuffer buffer, int sz, long boundary, long searchStart, long searchEnd) {
if (searchStart >= searchEnd) return;
long bv = buffer.currentValue();
long av = get(searchStart);
long pos = searchStart;
while (bv <= boundary && buffer.hasMore()) {
if (bv < av) {
if (!buffer.retainAndAdvance()) break;
bv = buffer.currentValue();
continue;
}
else if (bv == av) {
if (!buffer.rejectAndAdvance()) break;
bv = buffer.currentValue();
continue;
}
pos += sz;
if (pos < searchEnd) {
av = get(pos);
}
else {
break;
}
}
}
}