xref: /aosp_15_r20/external/zlib/contrib/optimizations/insert_string.h (revision 86ee64e75fa5f8bce2c8c356138035642429cd05)
1*86ee64e7SAndroid Build Coastguard Worker /* insert_string.h
2*86ee64e7SAndroid Build Coastguard Worker  *
3*86ee64e7SAndroid Build Coastguard Worker  * Copyright 2019 The Chromium Authors
4*86ee64e7SAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*86ee64e7SAndroid Build Coastguard Worker  * found in the Chromium source repository LICENSE file.
6*86ee64e7SAndroid Build Coastguard Worker  */
7*86ee64e7SAndroid Build Coastguard Worker 
8*86ee64e7SAndroid Build Coastguard Worker #ifndef INSERT_STRING_H
9*86ee64e7SAndroid Build Coastguard Worker #define INSERT_STRING_H
10*86ee64e7SAndroid Build Coastguard Worker 
11*86ee64e7SAndroid Build Coastguard Worker #ifndef INLINE
12*86ee64e7SAndroid Build Coastguard Worker #if defined(_MSC_VER) && !defined(__clang__)
13*86ee64e7SAndroid Build Coastguard Worker #define INLINE __inline
14*86ee64e7SAndroid Build Coastguard Worker #else
15*86ee64e7SAndroid Build Coastguard Worker #define INLINE inline
16*86ee64e7SAndroid Build Coastguard Worker #endif
17*86ee64e7SAndroid Build Coastguard Worker #endif
18*86ee64e7SAndroid Build Coastguard Worker 
19*86ee64e7SAndroid Build Coastguard Worker #include <stdint.h>
20*86ee64e7SAndroid Build Coastguard Worker 
21*86ee64e7SAndroid Build Coastguard Worker /**
22*86ee64e7SAndroid Build Coastguard Worker  * Some applications need to match zlib DEFLATE output exactly [3]. Use the
23*86ee64e7SAndroid Build Coastguard Worker  * canonical zlib Rabin-Karp rolling hash [1,2] in that case.
24*86ee64e7SAndroid Build Coastguard Worker  *
25*86ee64e7SAndroid Build Coastguard Worker  *  [1] For a description of the Rabin and Karp algorithm, see "Algorithms"
26*86ee64e7SAndroid Build Coastguard Worker  *      book by R. Sedgewick, Addison-Wesley, p252.
27*86ee64e7SAndroid Build Coastguard Worker  *  [2] https://www.euccas.me/zlib/#zlib_rabin_karp and also "rolling hash"
28*86ee64e7SAndroid Build Coastguard Worker  *      https://en.wikipedia.org/wiki/Rolling_hash
29*86ee64e7SAndroid Build Coastguard Worker  *  [3] crbug.com/1316541 AOSP incremental client APK package OTA upgrades.
30*86ee64e7SAndroid Build Coastguard Worker  */
31*86ee64e7SAndroid Build Coastguard Worker #ifdef CHROMIUM_ZLIB_NO_CASTAGNOLI
32*86ee64e7SAndroid Build Coastguard Worker #define USE_ZLIB_RABIN_KARP_ROLLING_HASH
33*86ee64e7SAndroid Build Coastguard Worker #endif
34*86ee64e7SAndroid Build Coastguard Worker 
35*86ee64e7SAndroid Build Coastguard Worker /* ===========================================================================
36*86ee64e7SAndroid Build Coastguard Worker  * Update a hash value with the given input byte (Rabin-Karp rolling hash).
37*86ee64e7SAndroid Build Coastguard Worker  * IN  assertion: all calls to UPDATE_HASH are made with consecutive input
38*86ee64e7SAndroid Build Coastguard Worker  *    characters, so that a running hash key can be computed from the previous
39*86ee64e7SAndroid Build Coastguard Worker  *    key instead of complete recalculation each time.
40*86ee64e7SAndroid Build Coastguard Worker  */
41*86ee64e7SAndroid Build Coastguard Worker #define UPDATE_HASH(s, h, c) (h = (((h) << s->hash_shift) ^ (c)) & s->hash_mask)
42*86ee64e7SAndroid Build Coastguard Worker 
43*86ee64e7SAndroid Build Coastguard Worker /* ===========================================================================
44*86ee64e7SAndroid Build Coastguard Worker  * Insert string str in the dictionary and set match_head to the previous head
45*86ee64e7SAndroid Build Coastguard Worker  * of the hash chain (the most recent string with same hash key). Return
46*86ee64e7SAndroid Build Coastguard Worker  * the previous length of the hash chain.
47*86ee64e7SAndroid Build Coastguard Worker  * If this file is compiled with -DFASTEST, the compression level is forced
48*86ee64e7SAndroid Build Coastguard Worker  * to 1, and no hash chains are maintained.
49*86ee64e7SAndroid Build Coastguard Worker  * IN  assertion: all calls to INSERT_STRING are made with consecutive input
50*86ee64e7SAndroid Build Coastguard Worker  *    characters and the first MIN_MATCH bytes of str are valid (except for
51*86ee64e7SAndroid Build Coastguard Worker  *    the last MIN_MATCH-1 bytes of the input file).
52*86ee64e7SAndroid Build Coastguard Worker  */
insert_string(deflate_state * const s,const Pos str)53*86ee64e7SAndroid Build Coastguard Worker local INLINE Pos insert_string(deflate_state* const s, const Pos str) {
54*86ee64e7SAndroid Build Coastguard Worker   Pos ret;
55*86ee64e7SAndroid Build Coastguard Worker /* insert_string dictionary insertion: ANZAC++ hasher
56*86ee64e7SAndroid Build Coastguard Worker  * significantly improves data compression speed.
57*86ee64e7SAndroid Build Coastguard Worker  *
58*86ee64e7SAndroid Build Coastguard Worker  * Note: the generated compressed output is a valid DEFLATE stream, but will
59*86ee64e7SAndroid Build Coastguard Worker  * differ from canonical zlib output.
60*86ee64e7SAndroid Build Coastguard Worker  */
61*86ee64e7SAndroid Build Coastguard Worker #if defined(USE_ZLIB_RABIN_KARP_ROLLING_HASH)
62*86ee64e7SAndroid Build Coastguard Worker   UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH - 1)]);
63*86ee64e7SAndroid Build Coastguard Worker #else
64*86ee64e7SAndroid Build Coastguard Worker   uint32_t value;
65*86ee64e7SAndroid Build Coastguard Worker   // Validated for little endian archs (i.e. x86, Arm). YMMV for big endian.
66*86ee64e7SAndroid Build Coastguard Worker   zmemcpy(&value, &s->window[str], sizeof(value));
67*86ee64e7SAndroid Build Coastguard Worker   s->ins_h = ((value * 66521 + 66521) >> 16) & s->hash_mask;
68*86ee64e7SAndroid Build Coastguard Worker #endif
69*86ee64e7SAndroid Build Coastguard Worker 
70*86ee64e7SAndroid Build Coastguard Worker #ifdef FASTEST
71*86ee64e7SAndroid Build Coastguard Worker   ret = s->head[s->ins_h];
72*86ee64e7SAndroid Build Coastguard Worker #else
73*86ee64e7SAndroid Build Coastguard Worker   ret = s->prev[str & s->w_mask] = s->head[s->ins_h];
74*86ee64e7SAndroid Build Coastguard Worker #endif
75*86ee64e7SAndroid Build Coastguard Worker   s->head[s->ins_h] = str;
76*86ee64e7SAndroid Build Coastguard Worker 
77*86ee64e7SAndroid Build Coastguard Worker   return ret;
78*86ee64e7SAndroid Build Coastguard Worker }
79*86ee64e7SAndroid Build Coastguard Worker 
80*86ee64e7SAndroid Build Coastguard Worker #endif /* INSERT_STRING_H */
81