fixed sliceBytes supports

This commit is contained in:
lionsoul2014 2025-12-29 19:34:12 +08:00
parent 56606de2f6
commit 245bbaa366
1 changed files with 47 additions and 14 deletions

View File

@ -4,6 +4,8 @@
package org.lionsoul.ip2region.xdb; package org.lionsoul.ip2region.xdb;
import java.io.IOException;
// xdb byte buffer which used to instead of the byte array // xdb byte buffer which used to instead of the byte array
// when the size of the xdb file is greater than 2^32 << 2; // when the size of the xdb file is greater than 2^32 << 2;
// xdb file v4 is designed to be a maximum of 2^32 bytes in size. // xdb file v4 is designed to be a maximum of 2^32 bytes in size.
@ -14,21 +16,44 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
public class LongByteArray { public class LongByteArray {
// slice bytes
// if it is greater than the 0 we will use the fixed slice bytes
// or we use the dynamic slice bytes.
private final int sliceBytes;
// when EOF is true means we cannot call the #append anymore.
// for fixed slice bytes only.
private boolean _eof = false;
// byte buffer list // byte buffer list
private final List<byte[]> buffs = new ArrayList<byte[]>(); private final List<byte[]> buffs = new ArrayList<byte[]>();
private long length; private long length;
public LongByteArray() { public LongByteArray() {
this.length = 0; this.length = 0;
this.sliceBytes = -1;
} }
public LongByteArray(byte[] buff) { public LongByteArray(int sliceBytes) {
buffs.add(buff); assert sliceBytes != 0;
length = buff.length; assert sliceBytes <= Searcher.MAX_WRITE_BYTES;
this.sliceBytes = sliceBytes;
} }
// append new buffer // append new buffer
public void append(final byte[] buffer) { public void append(final byte[] buffer) throws IOException{
// check and assert the slice bytes
if (sliceBytes > 0) {
if (_eof) {
throw new IOException("buffer array closed (EOF=true)");
} else if (buffer.length != sliceBytes) {
// mark the buffer array as closed
// since the last buffer block bytes is not equal to the expected #sliceBytes
_eof = true;
}
}
buffs.add(buffer); buffs.add(buffer);
length += buffer.length; length += buffer.length;
} }
@ -44,17 +69,25 @@ public class LongByteArray {
// internal method to determine the position of the specified offset // internal method to determine the position of the specified offset
private Position determinate(final long offset) { private Position determinate(final long offset) {
int index = 0, position = 0, buffLen = buffs.size(); int index = 0, position = 0, buffLen = buffs.size();
long curIndex = 0; if (sliceBytes > 0) {
for (index = 0; index < buffLen; index++) { // simply some math calcs to determine the offset
final byte[] buff = buffs.get(index); index = (int) (offset / sliceBytes);
if (curIndex + buff.length < offset) { position = (int) (offset - (index * sliceBytes));
curIndex += buff.length; // position = (int) (offset % sliceBytes);
continue; } else {
} // loop the buffer to determine the offset
long curIndex = 0;
for (index = 0; index < buffLen; index++) {
final byte[] buff = buffs.get(index);
if (curIndex + buff.length < offset) {
curIndex += buff.length;
continue;
}
// matched and calc the position // matched and calc the position
position = (int) (offset - curIndex); position = (int) (offset - curIndex);
break; break;
}
} }
return new Position(index, position); return new Position(index, position);