Space-Efficient Construction of Compressed Indexes in Deterministic Linear Time
arxiv.org
arxiv.org
Yes, it is a theoretical paper and then the presentation focuses on what is needed in such a paper: to establish that the big-Oh complexity can be reached. Some theoretical papers will never become practical, but we believe this one can. However, this will require a fair amount of algorithm engineering, to take the important theoretical ideas and implement them with common sense, changing theoretically appealing but practically useless modules by others that work better, even if they do not reach the desired worst-case complexity. A promising aspect of this algorithm is that it is easily parallelizable (the batched queries). A postdoc of mine that has experience in multithreading and compact data structures is already working on this. I won't dare to say how competitive will be the resulting LZ-parsing algorithm, though.
We have had some experiences with good theoretical results whose implementation looks unsurmountable but that turned out to work very well after some algorithm engineering. An example is our work on top-k document retrieval: http://epubs.siam.org/doi/abs/10.1137/140998949 http://dl.acm.org/citation.cfm?id=3043958
Another well-known case is the first paper on the FM-index, with constants like sigma^sigma multiplying the space, and its current realizations, e.g. Burrows-Wheeler Aligner.
In this case, I think it will not be that hard, but still it will not be a matter of just translating the algorithm into code.
Best, Gonzalo
There are already bioinformatics tools such as BowTie that use the Burrows-Wheeler transform. https://en.wikipedia.org/wiki/Burrows%E2%80%93Wheeler_transf...
I think the important thing here is that the running time is deterministic, which is important if your query usually runs for days or even weeks!
(edited)
As the authors point out, existing algorithms for the construction of the compressed suffix tree require space that is proportional to the alphabet size. When we work with limited alphabets, like DNA, this factor is small and we tend to not worry about it. Many real-world data sets do have larger alphabet sizes, and so there is a need to efficiently generate the CST for them. Removing the alphabet-size bound on the space required for construction is a big deal. Existing methods require huge amounts of space to construct the CST or CSA (compressed suffix array) for large alphabets, and are barely practical to use.
In practice results of this kind have proceeded implementations that are usable by a year or more. Libraries like sdsl-lite have accelerated the rate at which implementations get into the hands of compressed data structure researchers in much the same way that R did for statistical models, so hopefully we can see benefits of this result sooner.
Unfortunately, it will take a deeper reading of the paper by someone who is more intimately involved in this research to be able to describe exactly why this result may not be practical. A quick read does not suggest any obvious problems, the authors have a good track record and are very positive about many follow-on results (see conclusions).
Without having read the paper in detail, SODA (the conference where it was presented) papers do have a reputation for being very theoretical, though, so it may not be implemented any time soon.
There are actually several tricks at the "string algorithm" level. I didn't invent any of them, but no other search tool combines all of them AFAIK. They are:
* Heuristic for choosing the skip character in boyer moore. (Pick rare bytes.)
* Roll UTF-8 decoding into the regex automaton.
* Use SIMD for multiple string literal search. (This is an unpublished algorithm from Intel's Hyperscan project.)
There was also significant work required for scaling glob matching. Some popular repositories have gitignore files with over 3000 rules.
These are important because ripgrep isn't just for searching code repositories. It should be able to do most things that grep can do, but faster. (The smarter UTF-8 handling is particularly beneficial when searching non-ASCII text.)
Within the context of this thread though, and as someone who has written a linear time suffix array algorithm, the suffix array isn't particularly well suited to the problem of code search. Its constant factors are just too high. Generating an index would take a long time. (Although I haven't read the OP yet.)
> some system call tricks for reading files as quickly as possible.
ripgrep does two different types of searches. One uses memory maps. The other uses standard `read` calls. The latter is actually faster on Linux when searching code repositories. So no real tricks there. :-)
(I wrote an implementation of Ukkonen's suffix tree algorithm in C as maybe my second C program, it was pretty frustrating for a long time)
> (I wrote an implementation of Ukkonen's suffix tree algorithm in C as maybe my second C program, it was pretty frustrating for a long time)
Oh dear. You are brave. I briefly considered implementing Ukkonen's algorithm, but ran away scared. :-)
The reason why I wrote the SAIS implementation was because I am generally interested in text search, and because I was interested in exploring the idea of building an index around suffix arrays. Once I finished my implementation and realized that the cutting edge SACA algorithm (at the time) was as slow as it was, I mostly gave up that idea.
Since then, I've been itching to find use cases for it. As a former computational biologist, I'm familiar with how they are used in that field, but I've been looking for other places as well. Haven't found one yet, although I can think of some specialized (hypothetical) things where it might be useful.
The paper under discussion here is about a new way to create an index that also takes time ~linear in the size of the files to be searched, although presumably with a higher constant factor than just searching those files. After you have the index it's possible to search it in time linear in the length of the query rather than the files. This is much faster, but requires storing an index that is at least as large as the original file set, and keeping it up to date as things are changed etc.
If nothing else, I think it is possible to retrieve a complete file from any index that lets you search for substrings and get a full string and position in the file back. Just search for all length 1 substrings, get a map from position -> string, then reconstruct the file from that.
I doubt it's worth storing files this way, because turning the index back into the file sounds very slow. I'd rather just store the file and the index, the time v. space tradeoff seems like a good one if you really care about search performance. That said, I use The Silver Searcher, and it's fast enough with no index that I don't think any of this stuff is worth the effort for searching text files on a file system.
edit: why the downvotes? Theoretical CS academics basically do math and very few write any actual code to supplement their papers.
[0] http://succinct.cs.berkeley.edu/wp/wordpress/ [1] https://www.youtube.com/watch?v=R_SHYey7eas (Video)
As a somewhat expert in the field I doubt that this paper has any practical implications.
The primary motivation for unlimited LZ is text indexing. You can build text indexes based on LZ parsing and achieve ridiculous compression ratios with repetitive data (e.g. versioned documents). The query performance depends on the length of the dependency chains in the parsing, so you want to use as long windows as possible.
He already has some interesting code :)
I don't have access to that paper, but "compressing indexes" is likely to be slow, no matter how is implemented: fastest LZ77 using hashing relies on doing few operations per input byte. So no matter if the hash table space could be reduced or not, the speed would not be likely to be faster (anyway, you can trade hash table size vs compression ratio, even without that new technique).
If you must preserve ability to decompress by zlib, there are different implementations of a DEFLATE compressor that are better than zlib (either faster or better compression ratio).
A DEFLATE compressor needs to keep a data structure that is able to answer the query "where in the last 32,768 bytes of input there are occurrences of the exact 3 bytes I'm looking at? If possible, check whether the 4th byte matches too and find the longest match. Among matches equally long, prefer those which are closer". For a 32KB window, a data structure that always finds the best match is not large, unless you're on a microcontroller. The size of the data structure becomes a problem when the window is large.