* @throws StoreDataCorruptedException
*/
public int garbageSweep(final String filePath) throws StoreException,
StoreClassNotFoundException, StoreDataCorruptedException {
numberOFGarbaged = 0;
PersistantDataRecordIdentifierSet toPreserveSet = null;
try {
toPreserveSet = new PersistantDataRecordIdentifierSet(filePath);
toPreserveSet.startService(true);
store.getClassNameManager().getAllDataRecordIdentifiers(
toPreserveSet);
store.getGarbageManager()
.getCandidateRecordAllDataRecordIdentifiers(toPreserveSet);
store.getGarbageManager().getLinkRecordAllDataRecordIdentifiers(
toPreserveSet);
store.getGarbageManager()
.getToGarbageRecordAllDataRecordIdentifiers(toPreserveSet);
toPreserveSet.add(Store.IDENTIFIER_FOR_STORE_HEADER);
final Deque<DataRecordIdentifier> que = new LinkedList<DataRecordIdentifier>();
DataRecordIdentifier dataRecordIdentifier = Store.IDENTIFIER_FOR_ROOT;
que.add(dataRecordIdentifier);
toPreserveSet.add(dataRecordIdentifier);
storeSaver.resetModificationCount();
while ((dataRecordIdentifier = que.pollFirst()) != null) {
final ObjectLinkTreeNode objectLinkTreeNode = objectIOManager
.getObjectLinkTreeNode(dataRecordIdentifier);
final DataRecordIdentifier[] referencedList = objectLinkTreeNode
.getReferencedList();
for (DataRecordIdentifier referenced : referencedList) {
if (toPreserveSet.add(referenced)) {
que.add(referenced);
storeSaver.performModificationDone();
}
}
}
final IHeapDataManager dataManager = storeSaver.getDataManager();
if (LOGGER.isInfoEnabled()) {
final int numberOfDataRecord = dataManager
.getNumberOfDataRecord();
LOGGER.info("total number of data record " + numberOfDataRecord
+ ", " + toPreserveSet.size() + " to preserve");
}
final Iterator<DataRecordIdentifier> iterator = dataManager
.dataRecordIterator();
garbageStartNotify();
while (iterator.hasNext()) {
final DataRecordIdentifier existing = iterator.next();
garbageManager.removeFromCandidateAndOrFromToGarbage(existing);
if (!toPreserveSet.contains(existing)) {
if (linkRecordManager == null) {
dataManager.deleteDataRecord(existing);
} else {
linkRecordManager
.removeLinkIfExist(existing/* referenced */);
final ObjectLinkTreeNode objectLinkTreeNode = objectIOManager
.getObjectLinkTreeNode(existing);
dataManager.deleteDataRecord(existing);
final DataRecordIdentifier[] referencedList = objectLinkTreeNode
.getReferencedList();
for (DataRecordIdentifier referenced : referencedList) {
removeLink(existing/* referencing */, referenced);
}
}
numberOFGarbaged++;
notifyGarbaged();
}
storeSaver.performModificationDone();
}
storeSaver.saveModification();
if (LOGGER.isInfoEnabled()) {
LOGGER.info("end of garbage sweep");
}
} catch (GarbageException exception) {
throw new StoreException(exception);
} catch (ReferenceLinkGarbageException exception) {
throw new StoreException(exception);
} catch (HeapException exception) {
throw new StoreException(exception);
} catch (ObjectIOException exception) {
throw new StoreException(exception);
} catch (ObjectIOClassNotFoundException exception) {
throw new StoreClassNotFoundException(exception);
} catch (ObjectIODataRecordNotFoundException exception) {
throw new StoreException(exception);
} catch (ObjectIODataCorruptedException exception) {
throw new StoreDataCorruptedException(exception);
} finally {
if (toPreserveSet != null) {
try {
toPreserveSet.stopService(true);
} catch (Exception exception) {
// ignore error
LOGGER.error("closing set", exception);
}
}