На этом шаге мы рассмотрим использование внутреннего указателя B+ дерева.
Каждое открытое В+ дерево имеет указатель на свои узлы. В момент открытия или обновления В+ дерева указатель помещается перед началом дерева. Если вы обращаетесь к предикату key_next, имея указатель на последнем ключе, он будет помещен за пределами дерева. Всегда, когда указатель перемещается за пределы дерева, key_current завершается неуспешно.
Если же это ограничение неприемлемо, то можно использовать предикаты mykey_next, mykey_prev и mykey_search с гарантией, что указатель В+ дерева всегда находится внутри В+ дерева (если там есть хоть какие-то ключи).
predicates mykey_next(db_selector,bt_selector,ref) mykey_prev(db_selector,bt_selector,ref) mykey_search(db_selector,bt_selector,string,ref) clauses mykey_prev(Dba,Bt_selector,Ref):- key_prev(Dba,Bt_selector,Ref), !. mykey_prev(Dba,Bt_selector,Ref):- key_next(Dba,Bt_selector,Ref), fail. mykey_next(Dba,Bt_selector,Ref):- key_next(Dba,Bt_selector,Ref), !. mykey_next(Dba,Bt_selector,Ref):- key_prev(Dba,Bt_selector,Ref), fail. mykey_search(Dba,Bt_selector,Key,Ref):- key_search(Dba,Bt_selector,Key, Ref), !. mykey_search(Dba,Bt_selector,_,Ref):- key_current(Dba,Bt_selector,_,Ref), !. mykey_search(Dba,Bt_selector,_,Ref):- key_last(Dba,Bt_selector,Ref).
Вы можете использовать предикаты samekey_next и samekey_prev, определенные в следующем примере, для того, чтобы передвинуть указатель В+ дерева к следующему идентичному ключу, если дерево имеет дублируемые ключи.
predicates samekey_next(db_selector,bt_selector,ref) try_next(db_selector,bt_selector,ref,string) samekey_prev(db_selector,bt_selector,ref) try_prev(db_selector,bt_selector,ref,string) clauses samekey_next(Dba,Bt_selector,Ref):- key_current(Dba,Bt_selector,OldKey,_), try_next(Dba,Bt_selector,Ref,OldKey). try_next(Dba,Bt_selector,Ref,OldKey):- key_next(Dba,Bt_selector,Ref), key_current(Dba,Bt_selector,NewKey,_), NewKey=OldKey, !. try_next(Dba,Bt_selector,_,_):- key_prev(Dba,Bt_selector,_), fail. samekey_prev(Dba,Bt_selector,Ref):- key_current(Dba,Bt_selector,OldKey,_), try_prev(Dba,Bt_selector,Ref,OldKey). try_prev(Dba,Bt_selector,Ref,OldKey):- key_prev(Dba,Bt_selector,Ref), key_current(Dba,Bt_selector,NewKey,_), NewKey=OldKey, !. try_prev(Dba,Bt_selector,_,_):- key_next(Dba,Bt_selector,_), fail.
На следующем шаге мы рассмотрим изменение структуры базы данных.