їДетали реализации
Для того, что бы понять написанное ниже, Вы должны ознакомиться с
методом хранения деревьев в базах данных ( http://webscript.ru///www.intelligententerprise.com/001020/celko.shtml ),
предложенным Joe Celko ( http://webscript.ru///celko.com/ ), а так же
хорошо представлять себе, какие операции следует производить,
что бы перемещать узлы в дереве, хранящимся таким способом.
Функция устроена таким образом, что она пытается выполнить несколько
перемещений одним sql-запросом. Это может значительным образом
сократить общее время перемещения всех необходимых вершин в дереве,
поскольку для перемещения каждой отдельной вершины
может потребоваться пересчитать значительную часть дерева,
которую так же придется пересчитывать при перемещении остальных вершин.
Тем не менее, само построение такого sql-запроса -
довольно трудоемкая задача. При некоторых обстоятельствах
(при маленьком дереве и большом количестве перемещений)
может даже оказаться, что быстрее выполнить перемещения
несколькими sql-запросами.
Скорость построения sql-запроса в значительной степени зависит от того,
на скольких разных интервалах следует произвести пересчет узлов
дерева.
разных ( http://webscript.ru/#interval.diff )
интервалах. При перемещении нескольких узлов, количество разных ( http://webscript.ru/#interval.diff )
интервалов зависит от характера перемещения узлов.
Например, если некоторые узлы, являющиеся смежными братьми,
перемещаются в новую родительскую вершину в таком же порядке
(слева на право), как они располагались в исходной родительской вершине,
то число разных интервалов будет равно двум, как и при перемещении одной
вершины. В таком случае функция
даст значительное (максимальное) ускорение перемещения узлов дерева.
Если перемещается некоторый узел дерева А, а потом перемещается узел В,
который в исходном дереве был родительским для узла А,
то при перемещении узла В потребуется произвести пересчет не по двум
дополнительным разным ( http://webscript.ru/#interval.diff ) интервалам, а уже по трем
дополнительным разным ( http://webscript.ru/#interval.diff ) интервалам (интервал
для узла В раньше был одним интервалом, который включал в себя интервал для узла А, а
теперь это два разных интервала + отдельный интервал для узла А).
Не сложно посчитать, на скольких разных ( http://webscript.ru/#interval.diff ) интервалах
нужно будет пересчитать дерево, если потребуется так же переместить узел С,
который в исходном дереве являлся родительским для узла В.
Экспериментальным путем установлено, что в наихудшем случае
(когда по всему дереву
случайные вершины перемещаются в случайных направлениях;
дерево маленькое, в нем содержится всего 1000 вершин)
функция не будет вызывать замедления процесса перемещения, если
количество разных ( http://webscript.ru/#interval.diff ) интервалов, на которых следует произвести пересчет узлов,
не превышает 70.
Функция устроена таким образом, что при превышении этого лимита
она генерирует новый sql-запрос.
В большинстве реальных случаев, однако, перемещения будут выполняться
одним sql-запросом. Ограничение "70 разных ( http://webscript.ru/#interval.diff ) интервалов" означает,
что за один проход перемещается порядка 30-40 узлов в разных направлениях.
Если же узлы перемещаются в одном направлении, есть варианты, когда
узлы были и остаются смежными, то количество узлов, которые можно
переместить, не превысив это ограничение, возрастает.
Кроме того, если общее число узлов в дереве не превышает 36, то любое
количество перемещений в любых направлениях будет выполнено за один проход,
поскольку для такого дерева максимальное количество принципиально возможных
разных ( http://webscript.ru/#interval.diff )
интервалов равно 70 (для каждого узла - левое и правое значение; корневой узел
не может быть перемещен, и поэтому не учитывается).