Бесконечный цикл findSuccessor?

В настоящее время я имею дело с протоколом Chord.

Для каждого узла есть две функции, findSuccessor и closestPrecedingNode, которые задаются в виде псевдокода.

findSuccessor is:

n.findSuccessor(id)
  if(id is.in (n, successor])
    return successor;
  else
    n' = closestPrecedingNode(id);
    return n'.findSuccessor(id);

closestPrecedingNode is:

n.closestPrecedingNode(id)
  for i = m downto 1
    if(finger[i] is.in (n, id))
      return finger[i];
  return n;

Когда узел создается, его преемник изначально устанавливается на сам узел, а его таблица отпечатков пуста.

Теперь мой вопрос: что происходит, когда есть только один узел, и его запрашивают любой идентификатор, кроме его собственного идентификатора. Затем findSuccessor запускает блок else и вызывает closestPrecedingNode. Так как таблица finger пуста, сам узел возвращается к findSuccessor. Следовательно, n' равно n.

После этого findSuccessor вызывается для n', что является рекурсивным вызовом самого себя.

И тут у нас бесконечный цикл... или я что-то упускаю?

ПРИМЕЧАНИЕ. Псевдокод взят из Chord: A Scalable Peer- Протокол однорангового поиска для Интернет-приложений, стр. 5.


person Golo Roden    schedule 06.12.2012    source источник


Ответы (1)


Разработчик "jchord", кажется, согласен с вами, поскольку он добавляет следующий код в findSuccessor:

if (this == successor) {
    return this;
}

Но, кажется, есть более элегантное решение, более близкое к псевдокоду. При проверке того, находится ли идентификатор в интервале (n, преемник] (слева исключено, справа включено), сделайте эту проверку циклической. jDHTUQ, кажется, делает это следующим образом (начиная со строки 75. Предупреждение: Действительно уродливый код):

http://jdhtuq.svn.sourceforge.net/viewvc/jdhtuq/source_code/distributed_lookup_service/LookupService/src/co/edu/uniquindio/utils/hashing/Key.java?revision=63&view=markup

ИМХО, выполнение проверки интервала циклически кажется правильным. В документе, на который вы ссылаетесь, говорится (на странице 4):

Обозначение (a; b] обозначает отрезок кольца Аккордов, полученный движением по часовой стрелке от (но не включая) a до достижения (и включая) b.

В случае одного узла вы должны проверить,

id is.in (n, n]

что должно дать true, поскольку идентификатор находится внутри кольца, которое начинается сразу после n и заканчивается n.

person David Tanzer    schedule 10.12.2012
comment
Вот так, отлично :-). Таким образом, в основном это сводится к вопросу о том, что вы определяете как включенное в интервал... - person Golo Roden; 10.12.2012
comment
Сравнение между this и successor, о котором вы упомянули, тем не менее необходимо, потому что таблица finger может быть изначально пустой, но преемник уже может быть установлен на другой узел (например, непосредственно после соединения). Тогда if из findSuccessor может потерпеть неудачу, и тогда вам нужно это сравнение, чтобы избежать бесконечного цикла. - person Golo Roden; 25.12.2012
comment
Нет никаких шансов, что эта функция войдет в бесконечный цикл, потому что, если в DHT есть только один узел (k), то есть узел k является его собственным преемником, тогда любой произвольный идентификатор, включая его собственный, попадет в круговой интервал по часовой стрелке (k, k ]. - person ; 13.08.2016