]>
git.proxmox.com Git - ceph.git/blob - ceph/src/isa-l/igzip/igzip_icf_base.c
4 #include "huff_codes.h"
6 #include "igzip_level_buf_structs.h"
8 static inline void write_deflate_icf(struct deflate_icf
*icf
, uint32_t lit_len
,
9 uint32_t lit_dist
, uint32_t extra_bits
)
11 icf
->lit_len
= lit_len
;
12 icf
->lit_dist
= lit_dist
;
13 icf
->dist_extra
= extra_bits
;
16 static inline void update_state(struct isal_zstream
*stream
, uint8_t * start_in
,
17 uint8_t * next_in
, uint8_t * end_in
,
18 struct deflate_icf
*start_out
, struct deflate_icf
*next_out
,
19 struct deflate_icf
*end_out
)
21 stream
->next_in
= next_in
;
22 stream
->total_in
+= next_in
- start_in
;
23 stream
->avail_in
= end_in
- next_in
;
25 ((struct level_2_buf
*)stream
->level_buf
)->icf_buf_next
= next_out
;
26 ((struct level_2_buf
*)stream
->level_buf
)->icf_buf_avail_out
= end_out
- next_out
;
29 void isal_deflate_icf_body_base(struct isal_zstream
*stream
)
31 uint32_t literal
, hash
;
32 uint8_t *start_in
, *next_in
, *end_in
, *end
, *next_hash
;
33 struct deflate_icf
*start_out
, *next_out
, *end_out
;
34 uint16_t match_length
;
36 uint32_t code
, code2
, extra_bits
;
37 struct isal_zstate
*state
= &stream
->internal_state
;
38 uint16_t *last_seen
= state
->head
;
40 if (stream
->avail_in
== 0) {
41 if (stream
->end_of_stream
|| stream
->flush
!= NO_FLUSH
)
42 state
->state
= ZSTATE_FLUSH_READ_BUFFER
;
46 start_in
= stream
->next_in
;
47 end_in
= start_in
+ stream
->avail_in
;
50 start_out
= ((struct level_2_buf
*)stream
->level_buf
)->icf_buf_next
;
52 start_out
+ ((struct level_2_buf
*)stream
->level_buf
)->icf_buf_avail_out
/
53 sizeof(struct deflate_icf
);
56 while (next_in
+ ISAL_LOOK_AHEAD
< end_in
) {
58 if (next_out
>= end_out
) {
59 state
->state
= ZSTATE_CREATE_HDR
;
60 update_state(stream
, start_in
, next_in
, end_in
, start_out
, next_out
,
65 literal
= *(uint32_t *) next_in
;
66 hash
= compute_hash(literal
) & HASH_MASK
;
67 dist
= (next_in
- state
->file_start
- last_seen
[hash
]) & 0xFFFF;
68 last_seen
[hash
] = (uint64_t) (next_in
- state
->file_start
);
70 /* The -1 are to handle the case when dist = 0 */
71 if (dist
- 1 < IGZIP_HIST_SIZE
- 1) {
74 match_length
= compare258(next_in
- dist
, next_in
, 258);
76 if (match_length
>= SHORTEST_MATCH
) {
78 #ifdef ISAL_LIMIT_HASH_UPDATE
81 end
= next_hash
+ match_length
;
85 for (; next_hash
< end
; next_hash
++) {
86 literal
= *(uint32_t *) next_hash
;
87 hash
= compute_hash(literal
) & HASH_MASK
;
89 (uint64_t) (next_hash
- state
->file_start
);
92 get_len_icf_code(match_length
, &code
);
93 get_dist_icf_code(dist
, &code2
, &extra_bits
);
95 state
->hist
.ll_hist
[code
]++;
96 state
->hist
.d_hist
[code2
]++;
98 write_deflate_icf(next_out
, code
, code2
, extra_bits
);
100 next_in
+= match_length
;
106 get_lit_icf_code(literal
& 0xFF, &code
);
107 state
->hist
.ll_hist
[code
]++;
108 write_deflate_icf(next_out
, code
, NULL_DIST_SYM
, 0);
113 update_state(stream
, start_in
, next_in
, end_in
, start_out
, next_out
, end_out
);
115 assert(stream
->avail_in
<= ISAL_LOOK_AHEAD
);
116 if (stream
->end_of_stream
|| stream
->flush
!= NO_FLUSH
)
117 state
->state
= ZSTATE_FLUSH_READ_BUFFER
;
123 void isal_deflate_icf_finish_base(struct isal_zstream
*stream
)
125 uint32_t literal
= 0, hash
;
126 uint8_t *start_in
, *next_in
, *end_in
, *end
, *next_hash
;
127 struct deflate_icf
*start_out
, *next_out
, *end_out
;
128 uint16_t match_length
;
130 uint32_t code
, code2
, extra_bits
;
131 struct isal_zstate
*state
= &stream
->internal_state
;
132 uint16_t *last_seen
= state
->head
;
134 start_in
= stream
->next_in
;
135 end_in
= start_in
+ stream
->avail_in
;
138 start_out
= ((struct level_2_buf
*)stream
->level_buf
)->icf_buf_next
;
139 end_out
= start_out
+ ((struct level_2_buf
*)stream
->level_buf
)->icf_buf_avail_out
/
140 sizeof(struct deflate_icf
);
141 next_out
= start_out
;
143 while (next_in
+ 3 < end_in
) {
144 if (next_out
>= end_out
) {
145 state
->state
= ZSTATE_CREATE_HDR
;
146 update_state(stream
, start_in
, next_in
, end_in
, start_out
, next_out
,
151 literal
= *(uint32_t *) next_in
;
152 hash
= compute_hash(literal
) & HASH_MASK
;
153 dist
= (next_in
- state
->file_start
- last_seen
[hash
]) & 0xFFFF;
154 last_seen
[hash
] = (uint64_t) (next_in
- state
->file_start
);
156 if (dist
- 1 < IGZIP_HIST_SIZE
- 1) { /* The -1 are to handle the case when dist = 0 */
157 match_length
= compare258(next_in
- dist
, next_in
, end_in
- next_in
);
159 if (match_length
>= SHORTEST_MATCH
) {
161 #ifdef ISAL_LIMIT_HASH_UPDATE
164 end
= next_hash
+ match_length
;
168 for (; next_hash
< end
- 3; next_hash
++) {
169 literal
= *(uint32_t *) next_hash
;
170 hash
= compute_hash(literal
) & HASH_MASK
;
172 (uint64_t) (next_hash
- state
->file_start
);
175 get_len_icf_code(match_length
, &code
);
176 get_dist_icf_code(dist
, &code2
, &extra_bits
);
178 state
->hist
.ll_hist
[code
]++;
179 state
->hist
.d_hist
[code2
]++;
181 write_deflate_icf(next_out
, code
, code2
, extra_bits
);
184 next_in
+= match_length
;
190 get_lit_icf_code(literal
& 0xFF, &code
);
191 state
->hist
.ll_hist
[code
]++;
192 write_deflate_icf(next_out
, code
, NULL_DIST_SYM
, 0);
198 while (next_in
< end_in
) {
199 if (next_out
>= end_out
) {
200 state
->state
= ZSTATE_CREATE_HDR
;
201 update_state(stream
, start_in
, next_in
, end_in
, start_out
, next_out
,
207 get_lit_icf_code(literal
& 0xFF, &code
);
208 state
->hist
.ll_hist
[code
]++;
209 write_deflate_icf(next_out
, code
, NULL_DIST_SYM
, 0);
215 if (next_in
== end_in
) {
216 if (stream
->end_of_stream
|| stream
->flush
!= NO_FLUSH
)
217 state
->state
= ZSTATE_CREATE_HDR
;
220 update_state(stream
, start_in
, next_in
, end_in
, start_out
, next_out
, end_out
);