6.6.2 Katalogi w pamieci


Spis treści


KATALOGI W PAMIECI

         W celu przyspieszenia dostępu do pozycji katalogowych, cześć z nich jest przechowywana w pamięci. Pozycje które są przechowywane, mają długość ograniczoną przez stałą DCACHE_NAME_LEN.  Ograniczenie to zostało wprowadzone w celu nie obciążania pamięci. Pozycje katalogowe o nazwach dłuższych niż powyższa stała, nie są przechowywane w pamięci.

         Ogólnie rzecz ujmując w pamięci przechowywana jest tablica mieszająca (hash_table) . Pozycjami tej tablicy są wskaźniki (struct hash_list) do dwukierunkowych, cyklicznych list haszujących w których są przechowywane informacje ( struct dir_cash_entry) o pozycjach katalogowych.  Rozmiar tej tablicy jest okreslony przez stałą DCACHE_HASH_QUEUES.

 Funkcja mieszająca (hashfn) zależy od:
        - numeru i-węzła katalogu
        - długosci nazwy pozycji
        - nazwy pozycji, oraz
        - numeru  urządzenia

Tablica haszująca odpowiada za szybki dostęp do elementu jesli tylko jest on zapisany w pamięci.
Algorytm postępowania przy wyszukiwaniiu opisuje nam funkcja dcache_lookup(), natomiast przy dodawaniu nowych pozycji funkcja dcache_add.

          Na elementach list haszujących zbudowane są jednocześnie dwie kolejki lru - level1_cache i level2_cache.
 
          W level1 znajdują się elementy, nowo wstawiane do tablicy haszującej. Natomiast w level2 znajdują się te elementy do których już się odwoływano (przy pomocy funkcji dcache_lookup).
W pierwszej przechowujemy te elemety, które mogą nam się przydać, czyli na przykład wpisane do pamięci podczas odczytywania pozycji katalogowych, być może z niektórych z nich bedziemy korzystać, wtedy te "używane" zostaną przeniesione do drugiej. Otrzymujemy dwupoziomowy mechanizm klasyfikacji elementów, w którym ostatnio "używane" elementy zostaną usunięte w ostatniej kolejnosci.

        Wstawienie polega na: usunięciu z początku jednego elementu , zapisaniu na jego miejscu nowego i przesunięciu wskaźnika( na głowę kolejki) o jeden do przodu. W ten oto sposób otrzymujemy sytuację w której najdawniej "używane" elementy są na początku kolejki (i są w pierwszej kolejności usuwane).



Przykładowy schemat struktury danych przechowującej pozycje katalogowe w pamięci

     


Legenda
hl - struct hash_list
dce - struct dir_cash_entry
Strzałka:
             - zielona - wskaźnik h w strukturze dce
             - czerwona - przykładowa kolejka level1_cashe (zaznaczono przebieg tylko w jedną
                                  stronę, ale jest to kolejka dwukierunkowa)
             - niebieska - przykładowa kolejka level2_cashe (uwaga jak wyżej)

na czerwono i niebiesko zaznaczono te struktury dce, które są pierwszymi elementami w kolejkach (odpowiednio: level1 i level2) i na te wlasnie struktury wskazują zmienne (odpowiednio) level1_head i level2_head.
 
Na rysunku nie uwzględniono tablic wskaźników do elementów (kolejek level1 i level2).



Opis algorytmów dzialania
 

Struktury danych:

Funkcje obsługujące tablicę: Funkcje operujące na kolejkach: Funkcje do odwoływania się do pamięci: Inne:

void remove_hash(struct dr_cache_etry * de)
 { }    Powrót.
 


void add_hash(struct dir_cache_entry * de, struct hash_list * hash)
{ }    Powrót.
 


struct dir_cache_entry * find_entry(struct inode * dir, const char * name, int len, struct hash_list * hash)
{ }    Powrót.
 


void remove_lru(struct dir_cache_entry * de)
{ }    Powrót.
 


void add_lru(struct dir_cache_entry * de, struct dir_cache_entry *head)
{ }    Powrót.
 


void update_lru(struct dir_cache_entry * de)
{ }    Powrót.
 


void move_to_level2(struct dir_cache_entry * old_de, struct hash_list * hash)
{ }    Powrót.
 


int dcache_lookup(struct inode * dir, const char * name, int len, unsigned long * ino)
//Daje w wyniku : 0 - porażka, czyli nie znaleziono
//                          1 - znaleziono, i-węzeł na zmiennej ino
{ }    Powrót.
 


void dcache_add(struct inode * dir, const char * name, int len, unsigned long ino)
{ }



Bibliografia:


Sporzadził: Tomasz Chudzik