/* This file is part of the db4o object database http://www.db4o.com
Copyright (C) 2004 - 2011 Versant Corporation http://www.versant.com
db4o is free software; you can redistribute it and/or modify it under
the terms of version 3 of the GNU General Public License as published
by the Free Software Foundation.
db4o is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see http://www.gnu.org/licenses/. */
package com.db4o.consistency;
import java.util.*;
import com.db4o.foundation.*;
import com.db4o.internal.*;
class OverlapMap {
private Set<Pair<SlotDetail, SlotDetail>> _dupes = new HashSet<Pair<SlotDetail,SlotDetail>>();
private TreeIntObject _slots = null;
private final BlockConverter _blockConverter;
public OverlapMap(BlockConverter blockConverter) {
_blockConverter = blockConverter;
}
public void add(SlotDetail slot) {
if(TreeIntObject.find(_slots, new TreeIntObject(slot._slot.address())) != null) {
_dupes.add(new Pair<SlotDetail, SlotDetail>(byAddress(slot._slot.address()), slot));
}
_slots = (TreeIntObject) TreeIntObject.add(_slots, new TreeIntObject(slot._slot.address(), slot));
}
public Set<Pair<SlotDetail, SlotDetail>> overlaps() {
final Set<Pair<SlotDetail, SlotDetail>> overlaps = new HashSet<Pair<SlotDetail, SlotDetail>>();
final ByRef<SlotDetail> prevSlot = ByRef.newInstance();
TreeIntObject.traverse(_slots, new Visitor4<TreeIntObject>() {
public void visit(TreeIntObject tree) {
SlotDetail curSlot = (SlotDetail) tree._object;
if(isOverlap(prevSlot.value, curSlot)) {
overlaps.add(new Pair<SlotDetail, SlotDetail>(prevSlot.value, curSlot));
}
prevSlot.value = curSlot;
}
private boolean isOverlap(SlotDetail prevSlot, SlotDetail curSlot) {
if(prevSlot == null){
return false;
}
return prevSlot._slot.address() + _blockConverter.bytesToBlocks(prevSlot._slot.length()) > curSlot._slot.address();
}
});
return overlaps;
}
public Set<Pair<SlotDetail, SlotDetail>> dupes() {
return _dupes;
}
private SlotDetail byAddress(int address) {
TreeIntObject tree = (TreeIntObject) TreeIntObject.find(_slots, new TreeIntObject(address, null));
return tree == null ? null : (SlotDetail)tree._object;
}
}