public void remove() {
//Return early
if (doc == null)
{return;}
final int collectionId = this.doc.getCollection().getId();
final Lock lock = dbTokens.getLock();
for (byte currentSection = 0; currentSection <= QNAME_SECTION; currentSection++) {
//Not very necessary, but anyway...
switch (currentSection) {
case TEXT_SECTION :
case ATTRIBUTE_SECTION :
case QNAME_SECTION :
break;
default :
throw new IllegalArgumentException("Invalid section type in '" +
dbTokens.getFile().getName() + "' (inverted index)");
}
for (final Iterator i = words[currentSection].entrySet().iterator(); i.hasNext();) {
//Compute a key for the token
final Map.Entry entry = (Map.Entry) i.next();
final OccurrenceList storedOccurencesList = (OccurrenceList) entry.getValue();
final Object token = entry.getKey();
Value key;
if (currentSection == QNAME_SECTION) {
final QNameTerm term = (QNameTerm) token;
key = new QNameWordRef(collectionId, term.qname, term.term,
broker.getBrokerPool().getSymbols());
} else {
key = new WordRef(collectionId, token.toString());
}
final OccurrenceList newOccurencesList = new OccurrenceList();
os.clear();
try {
lock.acquire(Lock.WRITE_LOCK);
final Value value = dbTokens.get(key);
if (value == null)
{continue;}
//Add its data to the new list
final VariableByteArrayInput is = new VariableByteArrayInput(value.getData());
while (is.available() > 0) {
final int storedDocId = is.readInt();
final byte storedSection = is.readByte();
final int termCount = is.readInt();
//Read (variable) length of node IDs + frequency + offsets
final int length = is.readFixedInt();
if (storedSection != currentSection || storedDocId != this.doc.getDocId()) {
// data are related to another section or document:
// append them to any existing data
os.writeInt(storedDocId);
os.writeByte(storedSection);
os.writeInt(termCount);
os.writeFixedInt(length);
is.copyRaw(os, length);
} else {
// data are related to our section and document:
// feed the new list with the GIDs
NodeId previous = null;
for (int m = 0; m < termCount; m++) {
NodeId nodeId = broker.getBrokerPool()
.getNodeFactory().createFromStream(previous, is);
previous = nodeId;
final int freq = is.readInt();
// add the node to the new list if it is not
// in the list of removed nodes
if (!storedOccurencesList.contains(nodeId)) {
for (int n = 0; n < freq; n++) {
newOccurencesList.add(nodeId, is.readInt());
}
} else {
is.skip(freq);
}
}
}
}
//append the data from the new list
if (newOccurencesList.getSize() > 0) {
//Don't forget this one
newOccurencesList.sort();
os.writeInt(this.doc.getDocId());
os.writeByte(currentSection);
os.writeInt(newOccurencesList.getTermCount());
//Mark position
final int lenOffset = os.position();
//Dummy value : actual one will be written below
os.writeFixedInt(0);
NodeId previous = null;
for (int m = 0; m < newOccurencesList.getSize();) {
previous = newOccurencesList.getNode(m).write(previous, os);
int freq = newOccurencesList.getOccurrences(m);
os.writeInt(freq);
for (int n = 0; n < freq; n++) {
os.writeInt(newOccurencesList.getOffset(m + n));
}
m += freq;
}
//Write (variable) length of node IDs + frequency + offsets
os.writeFixedInt(lenOffset, os.position() -
lenOffset - LENGTH_NODE_IDS_FREQ_OFFSETS);
}
//Store the data
if(os.data().size() == 0)
{dbTokens.remove(key);}
else if (dbTokens.update(value.getAddress(), key,
os.data()) == BFile.UNKNOWN_ADDRESS) {
LOG.error("Could not update index data for token '" +
token + "' in '" + dbTokens.getFile().getName() +
"' (inverted index)");
//TODO : throw an exception ?
}
} catch (final LockException e) {
LOG.warn("Failed to acquire lock for '" +
dbTokens.getFile().getName() + "' (inverted index)", e);
//TODO : throw exception ? -pb
} catch (final IOException e) {
LOG.error(e.getMessage() + "' in '" +
dbTokens.getFile().getName() + "' (inverted index)", e);
//TODO : throw exception ? -pb
} finally {
lock.release(Lock.WRITE_LOCK);
os.clear();
}
}
words[currentSection].clear();
}