Шаг 99.
Visual Prolog.
Использование внутреннего указателя B+ дерева

    На этом шаге мы рассмотрим использование внутреннего указателя 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.

    На следующем шаге мы рассмотрим изменение структуры базы данных.




Предыдущий шаг Содержание Следующий шаг