1*27162e4eSAndroid Build Coastguard Worker# LZ4 Streaming API Example : Line by Line Text Compression 2*27162e4eSAndroid Build Coastguard Workerby *Takayuki Matsuoka* 3*27162e4eSAndroid Build Coastguard Worker 4*27162e4eSAndroid Build Coastguard Worker`blockStreaming_lineByLine.c` is LZ4 Streaming API example which implements line by line incremental (de)compression. 5*27162e4eSAndroid Build Coastguard Worker 6*27162e4eSAndroid Build Coastguard WorkerPlease note the following restrictions : 7*27162e4eSAndroid Build Coastguard Worker 8*27162e4eSAndroid Build Coastguard Worker - Firstly, read "LZ4 Streaming API Basics". 9*27162e4eSAndroid Build Coastguard Worker - This is relatively advanced application example. 10*27162e4eSAndroid Build Coastguard Worker - Output file is not compatible with lz4frame and platform dependent. 11*27162e4eSAndroid Build Coastguard Worker 12*27162e4eSAndroid Build Coastguard Worker 13*27162e4eSAndroid Build Coastguard Worker## What's the point of this example ? 14*27162e4eSAndroid Build Coastguard Worker 15*27162e4eSAndroid Build Coastguard Worker - Line by line incremental (de)compression. 16*27162e4eSAndroid Build Coastguard Worker - Handle huge file in small amount of memory 17*27162e4eSAndroid Build Coastguard Worker - Generally better compression ratio than Block API 18*27162e4eSAndroid Build Coastguard Worker - Non-uniform block size 19*27162e4eSAndroid Build Coastguard Worker 20*27162e4eSAndroid Build Coastguard Worker 21*27162e4eSAndroid Build Coastguard Worker## How the compression works 22*27162e4eSAndroid Build Coastguard Worker 23*27162e4eSAndroid Build Coastguard WorkerFirst of all, allocate "Ring Buffer" for input and LZ4 compressed data buffer for output. 24*27162e4eSAndroid Build Coastguard Worker 25*27162e4eSAndroid Build Coastguard Worker``` 26*27162e4eSAndroid Build Coastguard Worker(1) 27*27162e4eSAndroid Build Coastguard Worker Ring Buffer 28*27162e4eSAndroid Build Coastguard Worker 29*27162e4eSAndroid Build Coastguard Worker +--------+ 30*27162e4eSAndroid Build Coastguard Worker | Line#1 | 31*27162e4eSAndroid Build Coastguard Worker +---+----+ 32*27162e4eSAndroid Build Coastguard Worker | 33*27162e4eSAndroid Build Coastguard Worker v 34*27162e4eSAndroid Build Coastguard Worker {Out#1} 35*27162e4eSAndroid Build Coastguard Worker 36*27162e4eSAndroid Build Coastguard Worker 37*27162e4eSAndroid Build Coastguard Worker(2) 38*27162e4eSAndroid Build Coastguard Worker Prefix Mode Dependency 39*27162e4eSAndroid Build Coastguard Worker +----+ 40*27162e4eSAndroid Build Coastguard Worker | | 41*27162e4eSAndroid Build Coastguard Worker v | 42*27162e4eSAndroid Build Coastguard Worker +--------+-+------+ 43*27162e4eSAndroid Build Coastguard Worker | Line#1 | Line#2 | 44*27162e4eSAndroid Build Coastguard Worker +--------+---+----+ 45*27162e4eSAndroid Build Coastguard Worker | 46*27162e4eSAndroid Build Coastguard Worker v 47*27162e4eSAndroid Build Coastguard Worker {Out#2} 48*27162e4eSAndroid Build Coastguard Worker 49*27162e4eSAndroid Build Coastguard Worker 50*27162e4eSAndroid Build Coastguard Worker(3) 51*27162e4eSAndroid Build Coastguard Worker Prefix Prefix 52*27162e4eSAndroid Build Coastguard Worker +----+ +----+ 53*27162e4eSAndroid Build Coastguard Worker | | | | 54*27162e4eSAndroid Build Coastguard Worker v | v | 55*27162e4eSAndroid Build Coastguard Worker +--------+-+------+-+------+ 56*27162e4eSAndroid Build Coastguard Worker | Line#1 | Line#2 | Line#3 | 57*27162e4eSAndroid Build Coastguard Worker +--------+--------+---+----+ 58*27162e4eSAndroid Build Coastguard Worker | 59*27162e4eSAndroid Build Coastguard Worker v 60*27162e4eSAndroid Build Coastguard Worker {Out#3} 61*27162e4eSAndroid Build Coastguard Worker 62*27162e4eSAndroid Build Coastguard Worker 63*27162e4eSAndroid Build Coastguard Worker(4) 64*27162e4eSAndroid Build Coastguard Worker External Dictionary Mode 65*27162e4eSAndroid Build Coastguard Worker +----+ +----+ 66*27162e4eSAndroid Build Coastguard Worker | | | | 67*27162e4eSAndroid Build Coastguard Worker v | v | 68*27162e4eSAndroid Build Coastguard Worker ------+--------+-+------+-+--------+ 69*27162e4eSAndroid Build Coastguard Worker | .... | Line#X | Line#X+1 | 70*27162e4eSAndroid Build Coastguard Worker ------+--------+--------+-----+----+ 71*27162e4eSAndroid Build Coastguard Worker ^ | 72*27162e4eSAndroid Build Coastguard Worker | v 73*27162e4eSAndroid Build Coastguard Worker | {Out#X+1} 74*27162e4eSAndroid Build Coastguard Worker | 75*27162e4eSAndroid Build Coastguard Worker Reset 76*27162e4eSAndroid Build Coastguard Worker 77*27162e4eSAndroid Build Coastguard Worker 78*27162e4eSAndroid Build Coastguard Worker(5) 79*27162e4eSAndroid Build Coastguard Worker Prefix 80*27162e4eSAndroid Build Coastguard Worker +-----+ 81*27162e4eSAndroid Build Coastguard Worker | | 82*27162e4eSAndroid Build Coastguard Worker v | 83*27162e4eSAndroid Build Coastguard Worker ------+--------+--------+----------+--+-------+ 84*27162e4eSAndroid Build Coastguard Worker | .... | Line#X | Line#X+1 | Line#X+2 | 85*27162e4eSAndroid Build Coastguard Worker ------+--------+--------+----------+-----+----+ 86*27162e4eSAndroid Build Coastguard Worker ^ | 87*27162e4eSAndroid Build Coastguard Worker | v 88*27162e4eSAndroid Build Coastguard Worker | {Out#X+2} 89*27162e4eSAndroid Build Coastguard Worker | 90*27162e4eSAndroid Build Coastguard Worker Reset 91*27162e4eSAndroid Build Coastguard Worker``` 92*27162e4eSAndroid Build Coastguard Worker 93*27162e4eSAndroid Build Coastguard WorkerNext (see (1)), read first line to ringbuffer and compress it by `LZ4_compress_continue()`. 94*27162e4eSAndroid Build Coastguard WorkerFor the first time, LZ4 doesn't know any previous dependencies, 95*27162e4eSAndroid Build Coastguard Workerso it just compress the line without dependencies and generates compressed line {Out#1} to LZ4 compressed data buffer. 96*27162e4eSAndroid Build Coastguard WorkerAfter that, write {Out#1} to the file and forward ringbuffer offset. 97*27162e4eSAndroid Build Coastguard Worker 98*27162e4eSAndroid Build Coastguard WorkerDo the same things to second line (see (2)). 99*27162e4eSAndroid Build Coastguard WorkerBut in this time, LZ4 can use dependency to Line#1 to improve compression ratio. 100*27162e4eSAndroid Build Coastguard WorkerThis dependency is called "Prefix mode". 101*27162e4eSAndroid Build Coastguard Worker 102*27162e4eSAndroid Build Coastguard WorkerEventually, we'll reach end of ringbuffer at Line#X (see (4)). 103*27162e4eSAndroid Build Coastguard WorkerThis time, we should reset ringbuffer offset. 104*27162e4eSAndroid Build Coastguard WorkerAfter resetting, at Line#X+1 pointer is not adjacent, but LZ4 still maintain its memory. 105*27162e4eSAndroid Build Coastguard WorkerThis is called "External Dictionary Mode". 106*27162e4eSAndroid Build Coastguard Worker 107*27162e4eSAndroid Build Coastguard WorkerIn Line#X+2 (see (5)), finally LZ4 forget almost all memories but still remains Line#X+1. 108*27162e4eSAndroid Build Coastguard WorkerThis is the same situation as Line#2. 109*27162e4eSAndroid Build Coastguard Worker 110*27162e4eSAndroid Build Coastguard WorkerContinue these procedures to the end of text file. 111*27162e4eSAndroid Build Coastguard Worker 112*27162e4eSAndroid Build Coastguard Worker 113*27162e4eSAndroid Build Coastguard Worker## How the decompression works 114*27162e4eSAndroid Build Coastguard Worker 115*27162e4eSAndroid Build Coastguard WorkerDecompression will do reverse order. 116*27162e4eSAndroid Build Coastguard Worker 117*27162e4eSAndroid Build Coastguard Worker - Read compressed line from the file to buffer. 118*27162e4eSAndroid Build Coastguard Worker - Decompress it to the ringbuffer. 119*27162e4eSAndroid Build Coastguard Worker - Output decompressed plain text line to the file. 120*27162e4eSAndroid Build Coastguard Worker - Forward ringbuffer offset. If offset exceeds end of the ringbuffer, reset it. 121*27162e4eSAndroid Build Coastguard Worker 122*27162e4eSAndroid Build Coastguard WorkerContinue these procedures to the end of the compressed file. 123