diff options
author | pacien | 2018-12-03 18:16:04 +0100 |
---|---|---|
committer | pacien | 2018-12-03 18:16:04 +0100 |
commit | b616e8f5773631945962d4b1256f8f2d575e0da1 (patch) | |
tree | c3b2f731ad3ef692ff9edb133f852d190e07ad2f /src/lzss/matchtable.nim | |
parent | 200cb18aafa7f62fdca37ae8952b5e9c5bb3f25f (diff) | |
download | gziplike-b616e8f5773631945962d4b1256f8f2d575e0da1.tar.gz |
optimise lzss prefix lookup with custom hashmap
Diffstat (limited to 'src/lzss/matchtable.nim')
-rw-r--r-- | src/lzss/matchtable.nim | 32 |
1 files changed, 15 insertions, 17 deletions
diff --git a/src/lzss/matchtable.nim b/src/lzss/matchtable.nim index cc04f49..879f47d 100644 --- a/src/lzss/matchtable.nim +++ b/src/lzss/matchtable.nim | |||
@@ -15,25 +15,23 @@ | |||
15 | # along with this program. If not, see <https://www.gnu.org/licenses/>. | 15 | # along with this program. If not, see <https://www.gnu.org/licenses/>. |
16 | 16 | ||
17 | import tables | 17 | import tables |
18 | import matchring | ||
18 | 19 | ||
19 | type MatchTable*[K, V] = ref object | 20 | const matchGroupLength = 3 |
20 | matchLimit: int | 21 | const hashShift = 5 |
21 | table: TableRef[K, seq[V]] | 22 | const tableHeight = 0b1 shl 15 |
22 | 23 | ||
23 | proc initMatchTable*[K, V](keyType: typedesc[K], valueType: typedesc[V], matchLimit = 5): MatchTable[K, V] = | 24 | type MatchTable* = object |
24 | MatchTable[K, V](matchLimit: matchLimit, table: newTable[K, seq[V]]()) | 25 | table: array[tableHeight, MatchRing] |
25 | 26 | ||
26 | proc len*[K, V](matchTable: MatchTable[K, V]): int = | 27 | proc initMatchTable*(): MatchTable = |
27 | matchTable.table.len | 28 | result = MatchTable() |
28 | 29 | ||
29 | proc matchList*[K, V](matchTable: MatchTable[K, V], pattern: K): seq[V] = | 30 | proc hash(pattern: array[matchGroupLength, uint8]): int = |
30 | if matchTable.table.hasKey(pattern): | 31 | ((pattern[0].int shl (hashShift * 2)) xor (pattern[1].int shl hashShift) xor pattern[2].int) mod tableHeight |
31 | matchTable.table[pattern] | ||
32 | else: | ||
33 | newSeqOfCap[V](matchTable.matchLimit) | ||
34 | 32 | ||
35 | proc addMatch*[K, V](matchTable: MatchTable[K, V], pattern: K, value: V) = | 33 | proc addMatch*(matchTable: var MatchTable, pattern: array[matchGroupLength, uint8], index: int) = |
36 | var matchList = matchTable.matchList(pattern) | 34 | matchTable.table[hash(pattern)].addMatch(index) |
37 | if matchList.len >= matchTable.matchLimit: matchList.del(matchList.len - 1) | 35 | |
38 | matchList.insert(value) | 36 | proc candidates*(matchTable: MatchTable, pattern: array[matchGroupLength, uint8]): MatchRing = |
39 | matchTable.table[pattern] = matchList | 37 | matchTable.table[hash(pattern)] |