use of org.exist.storage.io.VariableByteArrayInput in project exist by eXist-db.
the class NativeValueIndex method remove.
private <T> void remove(final PendingChanges<T> pending, final FunctionE<T, Value, EXistException> dbKeyFn) {
final VariableByteOutputStream nodeIdOs = new VariableByteOutputStream();
for (final Map.Entry<T, List<NodeId>> entry : pending.changes.entrySet()) {
final T key = entry.getKey();
final List<NodeId> storedGIDList = entry.getValue();
final List<NodeId> newGIDList = new ArrayList<>();
os.clear();
try (final ManagedLock<ReentrantLock> bfileLock = lockManager.acquireBtreeWriteLock(dbValues.getLockName())) {
// Compute a key for the value
final Value searchKey = dbKeyFn.apply(key);
final Value value = dbValues.get(searchKey);
// Does the value already has data in the index ?
if (value != null) {
// Add its data to the new list
final VariableByteArrayInput is = new VariableByteArrayInput(value.getData());
while (is.available() > 0) {
final int storedDocId = is.readInt();
final int gidsCount = is.readInt();
final int size = is.readFixedInt();
if (storedDocId != this.doc.getDocId()) {
// data are related to another document:
// append them to any existing data
os.writeInt(storedDocId);
os.writeInt(gidsCount);
os.writeFixedInt(size);
is.copyRaw(os, size);
} else {
// data are related to our document:
// feed the new list with the GIDs
NodeId previous = null;
for (int j = 0; j < gidsCount; j++) {
final NodeId nodeId = broker.getBrokerPool().getNodeFactory().createFromStream(previous, is);
previous = nodeId;
// in the list of removed nodes
if (!containsNode(storedGIDList, nodeId)) {
newGIDList.add(nodeId);
}
}
}
}
// append the data from the new list
if (newGIDList.size() > 0) {
final int gidsCount = newGIDList.size();
// Don't forget this one
FastQSort.sort(newGIDList, 0, gidsCount - 1);
os.writeInt(this.doc.getDocId());
os.writeInt(gidsCount);
// Compute the new GID list
try {
NodeId previous = null;
for (final NodeId nodeId : newGIDList) {
previous = nodeId.write(previous, nodeIdOs);
}
final byte[] nodeIdsData = nodeIdOs.toByteArray();
// clear the buf for the next iteration
nodeIdOs.clear();
// Write length of node IDs (bytes)
os.writeFixedInt(nodeIdsData.length);
// write the node IDs
os.write(nodeIdsData);
} catch (final IOException e) {
LOG.warn("IO error while writing range index: {}", e.getMessage(), e);
// TODO : throw exception?
}
}
// dbValues.remove(value);
if (dbValues.update(value.getAddress(), searchKey, os.data()) == BFile.UNKNOWN_ADDRESS) {
LOG.error("Could not update index data for value '{}'", searchKey);
// TODO: throw exception ?
}
} else {
if (dbValues.put(searchKey, os.data()) == BFile.UNKNOWN_ADDRESS) {
LOG.error("Could not put index data for value '{}'", searchKey);
// TODO : throw exception ?
}
}
} catch (final EXistException | IOException e) {
LOG.error(e.getMessage(), e);
} catch (final LockException e) {
LOG.warn("Failed to acquire lock for '{}'", FileUtils.fileName(dbValues.getFile()), e);
// TODO : return ?
} finally {
os.clear();
}
}
pending.changes.clear();
}
use of org.exist.storage.io.VariableByteArrayInput in project exist by eXist-db.
the class NativeValueIndex method dropIndex.
private <T> void dropIndex(final int docId, final PendingChanges<T> pending, final FunctionE<T, Value, EXistException> dbKeyFn) throws EXistException, IOException {
for (final Map.Entry<T, List<NodeId>> entry : pending.changes.entrySet()) {
final T key = entry.getKey();
// Compute a key for the indexed value in the collection
final Value v = dbKeyFn.apply(key);
final Value value = dbValues.get(v);
if (value == null) {
continue;
}
final VariableByteArrayInput is = new VariableByteArrayInput(value.getData());
boolean changed = false;
os.clear();
while (is.available() > 0) {
final int storedDocId = is.readInt();
final int gidsCount = is.readInt();
final int size = is.readFixedInt();
if (storedDocId != docId) {
// data are related to another document:
// copy them (keep them)
os.writeInt(storedDocId);
os.writeInt(gidsCount);
os.writeFixedInt(size);
is.copyRaw(os, size);
} else {
// data are related to our document:
// skip them (remove them)
is.skipBytes(size);
changed = true;
}
}
// Store new data, if relevant
if (changed) {
if (os.data().size() == 0) {
// nothing to store:
// remove the existing key/value pair
dbValues.remove(v);
} else {
// modify the existing value for the key
if (dbValues.put(v, os.data()) == BFile.UNKNOWN_ADDRESS) {
LOG.error("Could not put index data for key '{}'", v);
// TODO : throw exception ?
}
}
}
}
pending.changes.clear();
}
Aggregations