}
}
public Collection<Hash> nearTo(final Hash endHash, InetSocketAddress address) {
Hash addrHash = Hash.of(address);
Line addrLine = getLine(addrHash);
if (addrLine == null) {
return Collections.emptyList(); // should always exist except in startup or offline, etc
}
// of the existing and visible cached neighbors, sort by distance to this end
List<Hash> visibleNeighbors = Lists.newArrayList(
Iterables.filter(addrLine.getNeighbors(),
new Predicate<Hash>() {
@Override
public boolean apply(Hash hash) {
Line line = getLine(hash);
return line != null && line.isVisible();
}
}));
Collections.sort(visibleNeighbors, new Comparator<Hash>(){
@Override
public int compare(Hash o1, Hash o2) {
return endHash.diffBit(o1) - endHash.diffBit(o2);
}
});
// console.log("near_to: see[]=" + JSON.stringify(see));
// console.log("near_to: line=" + JSON.stringify(line));
if (visibleNeighbors.isEmpty()) {
return Collections.emptyList();
}
Hash firstSeeHash = visibleNeighbors.get(0);
logger.debug(StringUtils.join(
new String[]{
"NEARTO " + endHash,
address.toString(),
endHash.toString(),
Integer.toString(addrLine.getNeighbors().size()),
">",
Integer.toString(visibleNeighbors.size()),
";",
firstSeeHash.toString(),
"=",
Integer.toString(addrLine.getEnd().diffBit(endHash))
}, " "));
// it's either us or we're the same distance away so return these results
if (firstSeeHash.equals(addrLine.getEnd())
|| (firstSeeHash.diffBit(endHash) == addrLine.getEnd().diffBit(endHash))) {
// this +end == this line then replace the neighbors cache with this result
// and each in the result walk and insert self into their neighbors
if (addrLine.getEnd().equals(endHash)) {
logger.debug("NEIGH for " + endHash + " was "
+ StringUtils.join(addrLine.getNeighbors(), ",")
+ " " + visibleNeighbors.size());
addrLine.getNeighbors().clear();
Iterables.addAll(addrLine.getNeighbors(),
Iterables.limit(visibleNeighbors, 5));
logger.debug("NEIGH for " + endHash + " is now "
+ StringUtils.join(addrLine.getNeighbors(), ",")
+ " " + visibleNeighbors.size());
for (Hash neighborHash : addrLine.getNeighbors()) {
Line neighborLine = getLine(neighborHash);
if (neighborLine == null || neighborLine == addrLine
|| neighborLine.getNeighbors().contains(endHash)) {
continue;
}
neighborLine.getNeighbors().add(endHash);
logger.debug("SEED " + address + " into " + neighborLine.getAddress());
}
}
logger.debug("SEE distance=" + endHash.diffBit(firstSeeHash)