Masarykova univerzita, Brno Fakulta informatiky
Bakalářská práce
Inteligentní vyhledávání na FTP
Vypracoval: Ondřej Holeček Vedoucí: Mgr. Jan Kasprzak Brno, červen 2002
Inteligentní vyhledávání na FTP
Prohlašuji, že tato práce je mým původním autorským dílem, které jsem vypracoval samostatně. Všechny zdroje, prameny a literaturu, které jsem při vypracování používal nebo z nich čerpal, v práci řádně cituji s uvedením úplného odkazu na příslušný zdroj.
Abstrakt Účelem tohoto projektu je zajistit návštěvníkovi FTP-serveru prostřednictvím WWW stránek větší komfort při vyhledávání požadovaných souborů. Program bude umět projít adresářovou strukturu a vhodně si uložit informace o nalezených adresářích a souborech do vlastní databáze. Další část programu potom bude v této databázi vyhledávat.
Program, který je součástí této práce, smí být volně šířen pod licencí GPL.
Ondřej Holeček
Obsah Úvod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Program dbfind . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Program walk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Návrh datových struktur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Nároky kladené na databázi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Reprezentace dat v databázi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Datové elementy ukládané do databáze . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Návrh algoritmů . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Základ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Buffering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Načtení symbolického linku . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Regulární výrazy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Zapisování do databáze . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 Strom symbolických linků . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Intervaly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Rozhraní na procházení databáze . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Vytváření databáze . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Vyhledávání . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Jak programy fungují . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 walk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 dbfind . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 Závěr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Použitá literatura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 Příloha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
i
Úvod Inteligentní vyhledávání na FTP Projekt bude rozdělen na dva samostatné programy. Program walk prohledá zadaný adresář a jeho obsah si uloží do databáze. Druhý program dbfind bude vyhledávat zadaný soubor v databázi na základě parametrů zadaných z příkazové řádky. Oba programy se svojí funkcí budou velmi podobat programům locate(1) a updatedb(1) s tím rozdílem, že dokáží prohledávat i uvnitř symbolických linků. To je hlavní problém, který se v této práci bude řešit. Kompletní zdrojové kódy k projektu jsou k dispozici na adresách: ftp://ftp.linux.cz/pub/linux/people/ondrej holecek www.fi.muni.cz/~xholece1/projekt
1.1 Program dbfind Program dokáže na základě předem vytvořené databáze vyhledávat soubory a adresáře. Vyhledávání bude možné jak pomocí přímého zadání jména souboru resp. adresáře, tak i zadáním regulárního výrazu. Program bude schopen vyhledávat od libovolného počátečního adresáře. Příklad vyhledávání: Předpokládejme, že kořenový adresář, od kterého je vytvořena souborová databáze, obsahuje tyto soubory, adresáře a symbolické linky: /pub/linux/soubor1 /pub/pub /pub/adr/test /pub/adr/pokus/soubor2 /pub/adr/pub /pub/adr/link1 → /pub/linux /pub/adr/link2 → /pub/adr/pokus /pub/adr/link3 → /pub/adr/ Poznámka: Bude-li se v následujícím textu hovořit o konkrétním adresáři/souboru a nebude-li explicitně řečeno jinak, bude se jednat o adresář/soubor z tohoto příkladu. Budeme-li vyhledávat soubory pomocí regulárního výrazu „.*pub.*ÿ, budou nalezeny tyto adresáře resp. soubory: /pub, /pub/pub, /pub/adr/pub. Soubor /pub/linux se na výstupu neobjeví i přesto, že v nadřazeném adresáři je slovo „pubÿ obsaženo. Slovo „linuxÿ podslovo „pubÿ neobsahuje a to je směrodatné. 1
Vyhledává-li program locate(1), najde všechny soubory, v jejichž cestě je slovo „pubÿ obsaženo. V uvedeném příkladu by locate(1) nalezl úplně všechno, protože slovo „pubÿ je jméno kořenového adresáře, vyskytuje se ve všech cestách. Ošetření symbolických linků: Jedná se o stěžejní problém, který se bude v tomto projektu řešit. Narazí-li dbfind při prohledávání na symbolický link (dále jen link), bude prohledávat i uvnitř tohoto linku, avšak pouze v místech, kam by se prohledávání bez tohoto linku nedostalo. Bude-li dbfind v tomto případě prohledávat od adresáře /pub/adr/, najde díky linku /pub/adr/link1 i soubor /pub/linux/soubor1, na výstupu však bude cesta k tomuto souboru vyjádřena pomocí linku. Tedy /link1/soubor1, nikoli /pub/linux/soubor1. Program také musí zajistit, aby se žádný soubor nevyhledával dvakrát. Tedy bude-li vyhledávání začínat v adresáři /pub, bude se /pub/adr/link2 ignorovat, protože ukazuje do již prohledávané oblasti. Výstup programu musí být vhodně přizpůsoben k dalšímu zpracování pro umístění na WWW. V první verzi programu se počítá s prostým sekvenčním vyhledáváním v databázi. V pozdějších verzích programu by mělo být možné i rychlé vyhledávání pomocí setříděného indexu. Toto prohledávání však bude fungovat pouze při přímém vyhledávání. Bude-li zadán požadavek na vyhledávání pomocí regulárního výrazu, bude se vyhledávat sekvenčně.
1.2 Program walk Tento program bude vytvářet databázi na základě prohledaného adresáře. Data v databázi musí být organizována co nejúsporněji. Program nebude potřeba optimalizovat na rychlost, protože se očekává, že se databáze souborů bude vytvářet pouze jednou za poměrně dlouhou dobu. Proces vytváření databáze bude spouštěn obvykle v nočních hodinách a bude mít tedy dostatek času. Adresář, od kterého se bude databáze vytvářet, musí být možné zadat z příkazového řádku. Oba programy, dbfind i walk by měly být napsány co nejpřehledněji. Vstup do programu dbfind bude zadáván anonymním uživatelem z WWW a je možné, že tento vstup nebude zcela korektní. Mohlo by tak dojít ke zhroucení programu, v horším případě k nabourání serveru.
2
Návrh datových struktur
2.1 Nároky kladené na databázi Aby bylo možné provést seriózní návrh databázové struktury, bude nezbytné si ujasnit, jaké nároky budou na databázi kladeny. Databáze musí být co nejmenší — Ušetří se tak místo na disku a zvýší se rychlost programu. Program nebude muset číst z disku velký objem dat a vyhledávání tak bude rychlejší. Bude-li to možné, měla by se velikost databáze blížit velikosti databáze vytvářené programem locate(1). Rychlé vyhledávání konkrétní cesty — Bude-li požadavek na vyhledání konkrétního místa v databázi, tzn. jednoho konkrétního souboru v konkrétní cestě, musí být možné tento soubor pomocí cesty pokud možno rychle vystopovat. Bude-li například požadováno vyhledávat v souborech počínaje určitým adresářem, musí být možné tuto cestu rychle najít a rozpoznat soubory, které v ní leží. Detekce zacyklení — Datová struktura musí umožnit snadnou detekci zacyklení. Bude-li se například prohledávat /pub/adr, narazí se na link3 který ukazuje zpět na tento adresář. Tento fakt se musí odhalit a předejít tak zacyklení programu. Datová struktura musí být vhodně navržena pro detekci takových zacyklení.
2.2 Reprezentace dat v databázi Myšlenka organizace dat v databázi je založena na tzv. závorkové notaci. Každý objekt, který se bude do databáze ukládat, bude obsahovat své jméno a informaci o typu objektu. Bude-li objektem adresář, budou za ním umístěny pomyslné závorky, ve kterých bude uzavřen jeho obsah. Příklad závorkové notace: pub{ linux{ pub soubor1 } adr{ pub link1 link2 link3 } } Aby bylo možné v databázi začít prohledávat od určitého adresáře, bude každá levá závorka obsahovat ještě informaci o umístění svého protějšku (pravé závorky). Žádost o vyhledání určitého souboru v určitém adresáři se potom bude řešit tak, že se nejprve vyhledá levá pomyslná závorka od adresáře, ve kterém se má vyhledávat. Tato závorka společně se svým protějškem vymezí interval, ve kterém se bude prohledávat. 3
V databázi se kromě adresáře jako takového bude rozlišovat ještě prázdný adresář, u kterého nebude nutné zapisovat závorky (ve kterých beztak nic nebude). Bude-li se do adresáře ukládat link, může nastat několik případů: • Jestliže link ukazuje na soubor, bude tento link považován za soubor a bude uložen stejným způsobem jako soubor. • Bude-li link ukazovat na prázdný adresář, bude uložen stejným způsobem jako prázdný adresář. • Ukazuje-li link na neprázdný adresář a tento adresář bude nadřazeným adresářem adresáře, ve kterém je link (například: /pub/adr/link2), uloží se taktéž jako prázdný adresář. Je zřejmé, že tento link nikdy nebude prohledáván dovnitř. • A konečně, bude-li link ukazovat na neprázdný adresář, který není podadresářem adresáře, ve kterém je link, uloží se k linku interval, který vymezuje tento adresář. Bude-li se v následujícím textu vyskytovat pojem interval, bude se jednat o dvě 4-bytová čísla, která udávají offset levé a pravé závorky, ve které je uložen adresář a jeho obsah. Kdybychom například zjistili interval určitého adresáře a celý tento interval ze souboru separovali, získali bychom vlastně novou databázi od tohoto počátečního adresáře. Samozřejmě aby byla databáze korektní, museli bychom všechny intervaly v takto vzniklé databázi dekrementovat o dolní hodnotu původního intervalu.
2.3 Datové elementy ukládané do databáze Aby byla formální struktura databáze úplná, bude nutné rozvrhnout paměťové rozložení jednotlivých datových elementů v databázi. Soubor:
F1
file namen
\01
Prázdný adresář:
E1
file namen
\01
Adresář:
{1
offset of „}ÿ4
file namen
Uzávěr adresáře:
}1
Link:
L1
offset of „{ÿ4
offset of „}ÿ4
\01
file namen
\01
Každý rámeček znázorňuje jeden datový blok. Dolní index u pravého okraje rámečku udává jeho velikost v bytech. Bude-li v dalším textu řeč o datovém elementu, bude tím myšlena jedna z těchto datových struktur.
4
Návrh algoritmů
Celý projekt je rozložen do několika samostatných souborů. Tato část dokumentace popisuje klíčové algoritmy, které se v projektu použily, a odkazuje přímo na zdrojový kód projektu, resp. na soubory, ve kterých je konkrétní algoritmus realizován.
3.1 Základ soubor: basic.c Než jsem začal pracovat na samotném projektu, vytvořil jsem nejprve jakousi knihovnu základních funkcí. Jde především o funkce xmalloc, xfree, xrealloc, xstrdup a xclose. Tyto funkce dělají v podstatě to samé jako jejich protějšky bez „xÿ, avšak kontrolují návratové hodnoty a v případě chyby ukončí program. (Není-li možné alokovat potřebnou paměť, nemá cenu pokračovat!) Kromě těchto funkcí stojí za zmínku ještě funkce FATAL, která se použije v případech, kdy dojde k chybě, kterou není možné ošetřit (například při prohledávání adresáře tento adresář někdo smaže). Funkce zajistí vypsání chybového hlášení a program ukončí.
3.2 Buffering soubor: buffering.c Při zápisu libovolných dat do souboru je nutné tato data zapisovat pokud možno sekvenčně. Zapisování je tak daleko efektivnější, hlava disku se nemusí pokaždé vystavovat na nové místo. Šetříme tak strojový čas i disk. Bude-li se do databáze zapisovat velké množství adresářů, bude nutné u každého adresáře zapsat zpětně k levé závorce offset pravé závorky. Uvědomíme-li si celkový počet adresářů, pro které by program musel takový zpětný zápis provádět, začneme brzy uvažovat o způsobu, jak tyto zpětné zápisy eliminovat. Algoritmus, který jsem za tímto účelem navrhnul, vychází z faktu, že zápis zpět se bude provádět většinou velmi blízko od aktuálního offsetu. Bude-li se zapisovat adresář, který obsahuje jen malé množství podadresářů, je zřejmé, že interval mezi složenými závorkami bude malý. Tedy, zápis zpět se bude provádět jen krátkou vzdálenost od právě zapisované pravé závorky. Princip tohoto algoritmu je jednoduchý. V paměti se neustále udržují dva buffery stejné velikosti. Dojde-li k požadavku na zápis, nezapisuje se přímo do souboru, ale pouze do prvního bufferu. Jakmile se první buffer zaplní, začne se
5
zapisovat do druhého. Jakmile je zaplněn i ten, první se uloží na disk a buffery se vymění. V případě požadavku na zápis zpět se nejprve rozpozná, zda není náhodou tento zápis možné provést ještě v rámci bufferů. Jestliže to možné není, poznamená se tento požadavek do zřetězeného seznamu a zapíše se pak najednou při zavírání bufferu. Bude-li na disku velké množství „velkýchÿ adresářů, bude jich málo a vystačíme si s prostým zápisem na disk. Bude-li na disku velké množství „malýchÿ adresářů, což obvykle bývá, zpětnému zápisu se vyhneme díky bufferování.
3.3 Načtení symbolického linku soubor: readlink.c Při zjišťování, kam ukazuje určitý symbolický link, je třeba kromě práce kterou vykoná klasická funkce readlink(3), provést ještě řadu dalších akcí. Především je potřeba zjistit přesnou cestu od kořene. To se provede tak, že program nejprve provede chdir na patřičný link a zjistí aktuální adresář voláním getcwd. Tím se vyřeší případy, kdy link ukazuje na jiný link nebo když link udává cestu relativně. (například: ../../jedna/dva). Dále je potřeba transformovat cestu na cestu relativní od počátečního adresáře. Bude-li se do databáze ukládat obsah adresáře /ftp a bude-li link ukazovat na /ftp/pub/linux, musí být cesta transformována na cestu relativní vzhledem k adresáři /ftp. Tedy na /pub/linux. Dále se zde rozpoznává, jestli případný link neukazuje do podadresáře vzhledem k adresáři, ve kterém je link obsažen, (viz odstavec 2.2).
3.4 Regulární výrazy soubor: re.c K realizaci vyhledávání pomocí regulárního výrazu jsem použil funkce z hlavičkového souboru regexp.h.
3.5 Zapisování do databáze soubor: bfdb.c V tomto souboru jsou obsaženy základní funkce pro zapisování jednotlivých elementů do databáze. Jsou to funkce: ddb write empty dir, ddb write file, ddb write dir BEGIN, ddb write dir END a ddb write link. Tyto funkce jako vstupní parametr očekávají popis konkrétního adresáře, linku nebo souboru a zapíší jej do databáze.
6
Pro zápis adresáře bylo potřeba vytvořit dvě funkce. ddb write dir BEGIN zajistí zápis levé závorky, volného místa pro offset a jméno adresáře. Místo, kam se má ukládat offset, však zatím není známé, program ho zjistí až po prozkoumání všech podadresářů, proto si pouze uloží do zásobníku pozici offsetu. Po prohledání celého adresáře pak funkce ddb write dir END zapíše pravou závorku. Je zřejmé, že teprve v tomto místě je známa pozice pravé závorky, proto funkce vybere ze zásobníku poznamenané místo, kam tuto informaci zpětně zapsat, a offset zapíše.
3.6 Strom symbolických linků soubor: litree.c Aby bylo možné po vytvoření databáze zpětně doplnit ke všem linkům patřičné ukazatele, musí si program během prohledávání zapamatovat cesty ke všem adresářům, na které nějaký link ukazoval. Narazí-li walk při prohledávání na link, který vyhovuje všem kritériím z odstavce 2.2, zapamatuje si adresář, na který ukazuje. Algoritmus vytvoří v paměti strom, který se podobá adresářové struktuře na disku. V tomto stromě jsou po prohledání uloženy všechny adresáře, na které ukazuje nějaký link. Ke každému takovému adresáři je poznamenán patřičný offset k odpovídajícímu linku v databázi.
3.7 Intervaly soubor: interval.c Jak již bylo dříve poznamenáno, každý adresář vymezuje v databázi jistý interval, který je určen párem složených závorek { a }. Je-li v databázi uložen link na adresář, poznamená se k němu právě tento interval. Algoritmy pracující s těmito intervaly jsou obsaženy právě v souboru interval.c. Každý interval se ukládá do základní struktury interval. Tato struktura obsahuje levou a pravou hranici daného intervalu. Kromě toho bude potřeba pracovat s množinou takových intervalů. Za tímto účelem obsahuje struktura interval ukazatel na další strukturu téhož typu. Získá se tak množina intervalů jako jednosměrný zřetězený seznam. Připomeňme, že dva intervaly mohou být pouze disjunktní nebo jeden je podmnožinou druhého. Je zřejmé, že jsou-li na disku dva různé adresáře a soubor je v prvním i druhém adresáři, pak je jeden adresář podadresářem druhého.
3.8 Rozhraní na procházení databáze soubor: find.c V tomto souboru se nacházejí nejdůležitější podprogramy, které prochází samotnou databázi. Funkcí rdb open se databáze otevře a následně se z ní mohou 7
funkcí rdb read načítat jednotlivé datové elementy. Soubor s databází je mapován do paměti pomocí volání mmap(2). Pro správné fungování programu musí systém tuto funkci podporovat (u Linuxu a většiny jiných UNIXů to není problém). Kromě těchto základních funkcí je zde důležitá funkce rdb skip dir. Načte-li se funkcí rdb read adresář, který chceme přeskočit (soubory ani adresáře v něm nás nezajímají), zavoláme tuto funkci a adresář se přeskočí. Je celkem zřejmé, jak se to provede. U každé levé závorky je v databázi zaznamenán offset pravé, není proto problém celý adresář přeskočit. Další důležitou funkcí je funkce rdb dir entry2. Tato funkce má jako svůj parametr jméno adresáře včetně cesty (zadáno klasickým zápisem např. /pub/linux). Výsledkem volání této funkce je interval, ve kterém se daný adresář nachází.
3.9 Vytváření databáze soubor: walk.c V tomto souboru jsou uloženy všechny funkce, které se starají o procházení všech souborů a adresářů na disku. Funkce dl readdir dokáže přečíst obsah celého adresáře (nikoli podadresářů). Tato funkce je dále volána z funkce walk, která zajistí rekurzivní procházení všech adresářů do hloubky. Za zmínku stojí i funkce dl qsort, která soubory před uložením setřídí. (Algoritmus QuickSort je zde implementován nad jednosměrným zřetězeným seznamem.) Všechny funkce jsou do značné míry závislé na přesném chování operačního systému. Program předpokládá, že se z každého adresáře dostaneme přechodem přes „..ÿ do jeho nadřazeného adresáře. Dále se předpokládá, že getcwd(3) vrátí cestu v přesném formátu. Tedy cesta musí začínat „/ÿ a končit jménem nejvyššího adresáře. Při návrhu tohoto algoritmu jsem uvažoval o tom, že by bylo pěkné, kdyby místo procházení všech adresářů bral program jako svůj vstup výstup programu find(1). Po krátké úvaze jsem však tuto možnost zavrhnul. Program find(1) svůj výstup nemá dostatečně vhodný. U jmen symbolických linků není uveden jejich protějšek nehledě na to, že by bylo nutné prohledávat do hloubky, což find(1) sice umí, ale vznikla by tak závislost na formátu vstupu. Program by mohl jen těžko odlišit případy, kdy mu někdo podstrčil (byť neúmyslně) špatný vstup, například spustil find(1) se špatným parametrem.
3.10 Vyhledávání soubor: dbfind.c Jde o samotný program, kde je implementován algoritmus pro inteligentní prohledávání linků. Algoritmus je zabudován ve funkci search interval. Tato funkce získá jako vstup interval, který má prohledat, a prohledá ho. Krom toho je 8
jako druhý parametr této funkce seznam intervalů, které při prohledávání budou přeskakovat. Funkce při prohledávání neustále sleduje, zda následující prohledávaný adresář nebyl už náhodou prohledán. Jestliže tomu tak bylo, adresář přeskočí. Narazí-li při prohledávání na link, uloží si jeho interval do fronty. Po prohledání celého adresáře si funkce zapamatuje prohledaný interval, vybere nový z vrcholu fronty a pokračuje ve hledání.
9
Jak programy fungují
Ovládání obou programů je velmi intuitivní. Spustíme-li kterýkoli z programů s parametrem -h, vypíše se jednoduchá nápověda, podle které se dá velmi snadno poznat, jak který program funguje. Přesto zde uvádím krátký popis jednotlivých parametrů.
4.1 walk walk [-o soubor] [-v] [-d adresář]
Projde adresářovou strukturu a výsledek hledání uloží do souboru. Program se ovládá z příkazové řádky pomocí parametrů: [ -o soubor ] . . . . . . . Soubor do kterého se bude ukládat databáze. [ -d adresář ] . . . . . . Jméno adresáře, od kterého se bude databáze vytvářet. [ -v ] . . . . . . . . . . . . . . Bude vypisovat procházené adresáře na terminál.
4.2 dbfind Vyhledává v databázi vytvořené programem walk. Parametry programu jsou: dbfind [-d soubor] [-f adresář] [-w reg. výraz] [-0] [ [ [ [
-d soubor ] . . . . . . . Jméno souboru s databází. -f adresář ] . . . . . . Jméno adresáře, od kterého se bude vyhledávat. -w soubor ] . . . . . . Regulární výraz (co se bude vyhledávat). -0 ] . . . . . . . . . . . . . . Jako oddělovač výstupu použít znak \0.
10
Závěr Po dokončení programu jsem provedl krátkou rekapitulaci toho, co se v programu podařilo více, co méně a co se nepodařilo vůbec. Hlavní problém, který se v projektu řešil — problém symbolických linků — se vyřešit podařilo. Bylo k tomu však potřeba značného úsilí a otázkou je, zda koncový uživatel (návštěvník http://ftp.linux.cz) toto úsilí ocení. Velikost databáze vytvořené z celého mého disku (244347 souborů) je asi o 20% větší než velikost databáze vytvořené programem locate(1) (pro tento účel používaným). Doba vyhledávání v databázi i vytváření databáze je asi o 5–10% delší. Velkou výhodou programu je bezesporu podpora regulárních výrazů. Na druhou stranu regulární výraz prohledávání zpomalí 5× až 10×. Jako test hotového programu jsem vytvořil databázi programem walk na počítači aisa adresáře /ftp/pub. Doba vytváření této databáze lehce překročila jednu hodinu (Zmíněný adresář se montuje přes NFS, což jeho procházení značně zpomaluje. Procházení lokálního disku bude zřejmě rychlejší.) a výsledný soubor s databází měl velikost 15083KB. Databáze stejného adresáře vytvořená programem locate(1) měla velikost 14085KB. Rychlost následného vyhledávání v této databázi programem dbfind mě mile překvapila. Zkoušel jsem vyhledat klíčová slova „redhatÿ a „pubÿ, doba prohledání celé databáze nebyla delší než 2 vteřiny. V porovnání s programem locate(1), je doba vyhledávání jen o zlomek delší.
5.1 Použitá literatura K sepsání této dokumentace mi jako pomůcka dobře posloužily knihy TEXBook naruby a Jemný úvod do TEXu. Bylo použito i několik TEXových maker, obsažených v digitální formě knihy Jemný úvod do TEXu. Potřebné informace o funkcích ze standardních unixových knihoven, které jsem neznal zpaměti, jsem hledal v manových stránkách. Další pomůckou mi byly stránky WWW, většinou www.google.com, žádná konkrétní stránka mi však jako důležitý zdroj informací nesloužila.
5.2 Příloha K projektu je přiložena disketa se souborem ftpdb-v0.9.tar.gz, který obsahuje aktuální verzi programu. (md5sum: c2d1124980a09e8bec65d5b7d0b28ae5)
11