Docfd - Design Context

Back to Docfd

Initial Motivation

Docfd was born out of my personal frustrations with existing search tools in the context of human text search.

This is not to say I think the tools are not well implemented or not well designed, this is just me saying I don’t fit into the usage patterns that these tools are designed for. In fact, given the specific intended usage patterns and constraints, I think most of these tools are likely implemented as well as one could.

So the following are not necessarily criticisms, but more of why they didn’t fit my (perhaps admittedly niche) criteria of being able to run locally on a not very powerful machine while providing “good” search results:

Design Decisions

Primary Use Case and Main Technical Requirements

The main use case Docfd targets is a user navigating through an unstructured folder of human text documents with a mix of text files and PDFs, at a scale more commonly seen at personal storage or small office level, e.g. a few hundred files to scan through at a time, using a relatively modern mid-tier system (1-1.5k AUD laptop).

To make the requirements a bit more concrete, we used a set of PDFs from PDF Corpora (specifically CC-MAIN-2021-31-PDF-UNTRUNCATED series, 0000.zip) as benchmark on a mid-tier level laptop with the following specification:

Component Details
CPU 13th Gen Intel(R) Core(TM) i5-1334U (4+8) @ 4.60 GHz
RAM 16GB
SSD SAMSUNG MZVL8512HELU-00BTW

0000.zip consists of 1k PDF documents with an average file size of 1.3 MiB.

After extensive use of Docfd myself for document management and navigation, I arrived at the following final set of technical requirements for collection of documents up to 1k in total:

Description Constraint
Docfd needs to index fresh files relatively quickly <5 minutes
Docfd needs to finish processing files already indexed significantly faster than unindexed files (otherwise what’s the point) <10 seconds
Docfd needs to not compete for RAM too heavily as it’s mainly run on a desktop environment rather than dedicated server <200MB upon start, before any user action

Why a Custom Search Engine

I opted to implement a custom search engine instead of using an off-the-shelf engine for a mix of reasons, listed in the order of relevance:

Suffice to say my choices would be different had this been an actual product that targets more general and larger use cases, as it is very difficult to beat the optimisation of existing search engines. And even if a custom query language is needed, a translation layer on top of the search engine’s native query language would likely cover all the practical cases.

Supporting Ad Hoc Workflow

Docfd only processes the current directory or the specified directories and files upon startup. Hashing is used to check if file has been previously indexed. This means there is no central storage requirement, and no background indexing.

In principle, this causes slower start-up time in the general case compared to programs with background indexing. But since the set of documents of interest is usually small (<100 documents), the start-up is often instantaneous.

Resource Constraints

There were some concessions made to avoid disrupting other desktop applications. One particularly noticeable choice is giving up storage of heavy indices in memory and instead rely on disk I/O via SQLite.

The tradeoff is that at larger scale (say a few thousand documents, depending on the sizes), Docfd will noticeably struggle where results will take seconds instead of less than a second to show up.

There are naturally middleground tactics that can be adopted, e.g. holding indices into a caching memory layer, and optionally pre-warming the layer with heuristics, but this was not further explored as basic design already suffices for the scale targetted.