Skip to main content

simd_brotli/enc/
combined_alloc.rs

1pub use crate::alloc::Allocator;
2
3#[cfg(feature = "std")]
4use alloc_stdlib::StandardAlloc;
5
6use super::cluster::HistogramPair;
7use super::command::Command;
8use super::entropy_encode::HuffmanTree;
9use super::hash_to_binary_tree::ZopfliNode;
10use super::histogram::{ContextType, HistogramCommand, HistogramDistance, HistogramLiteral};
11use super::interface::StaticCommand;
12use super::util::floatX;
13use super::{PDF, s16, v8};
14/*
15struct CombiningAllocator<T1, T2, AllocT1:Allocator<T1>, AllocT2:Allocator<T2>>(AllocT1, AllocT2);
16
17impl <T1, T2, AllocT1:Allocator<T1>, AllocT2:Allocator<T2>> CombiningAllocator<T1, T2, AllocT1, AllocT2> {
18  pub fn new(a: AllocT1, b: AllocT2) -> Self {
19    CombiningAllocator(a, b)
20  }
21}
22
23impl <T1, T2, AllocT1:Allocator<T1>, AllocT2:Allocator<T2>> Allocator<T1> for CombiningAllocator<T1, T2, AllocT1, AllocT2> {
24
25}
26
27
28impl <T1, T2, AllocT1:Allocator<T1>, AllocT2:Allocator<T2>> Allocator<T2> for CombiningAllocator<T1, T2, AllocT1, AllocT2> {
29
30}
31*/
32
33pub trait BrotliAlloc:
34    Allocator<u8>
35    + Allocator<u16>
36    + Allocator<i32>
37    + Allocator<u32>
38    + Allocator<u64>
39    + Allocator<Command>
40    + Allocator<super::util::floatX>
41    + Allocator<v8>
42    + Allocator<s16>
43    + Allocator<PDF>
44    + Allocator<StaticCommand>
45    + Allocator<HistogramLiteral>
46    + Allocator<HistogramCommand>
47    + Allocator<HistogramDistance>
48    + Allocator<HistogramPair>
49    + Allocator<ContextType>
50    + Allocator<HuffmanTree>
51    + Allocator<ZopfliNode>
52{
53}
54
55#[cfg(feature = "std")]
56impl BrotliAlloc for StandardAlloc {}
57
58pub struct CombiningAllocator<
59    AllocU8: Allocator<u8>,
60    AllocU16: Allocator<u16>,
61    AllocI32: Allocator<i32>,
62    AllocU32: Allocator<u32>,
63    AllocU64: Allocator<u64>,
64    AllocCommand: Allocator<Command>,
65    AllocFloatX: Allocator<floatX>,
66    AllocV8: Allocator<v8>,
67    AllocS16: Allocator<s16>,
68    AllocPDF: Allocator<PDF>,
69    AllocStaticCommand: Allocator<StaticCommand>,
70    AllocHistogramLiteral: Allocator<HistogramLiteral>,
71    AllocHistogramCommand: Allocator<HistogramCommand>,
72    AllocHistogramDistance: Allocator<HistogramDistance>,
73    AllocHistogramPair: Allocator<HistogramPair>,
74    AllocContextType: Allocator<ContextType>,
75    AllocHuffmanTree: Allocator<HuffmanTree>,
76    AllocZopfliNode: Allocator<ZopfliNode>,
77> {
78    alloc_u8: AllocU8,
79    alloc_u16: AllocU16,
80    alloc_i32: AllocI32,
81    alloc_u32: AllocU32,
82    alloc_u64: AllocU64,
83    alloc_c: AllocCommand,
84    alloc_f: AllocFloatX,
85    alloc_f32x8: AllocV8,
86    alloc_i16x16: AllocS16,
87    alloc_pdf: AllocPDF,
88    alloc_sc: AllocStaticCommand,
89    alloc_hl: AllocHistogramLiteral,
90    alloc_hc: AllocHistogramCommand,
91    alloc_hd: AllocHistogramDistance,
92    alloc_hp: AllocHistogramPair,
93    alloc_ct: AllocContextType,
94    alloc_ht: AllocHuffmanTree,
95    alloc_zn: AllocZopfliNode,
96}
97
98impl<
99    AllocU8: Allocator<u8>,
100    AllocU16: Allocator<u16>,
101    AllocI32: Allocator<i32>,
102    AllocU32: Allocator<u32>,
103    AllocU64: Allocator<u64>,
104    AllocCommand: Allocator<Command>,
105    AllocFloatX: Allocator<floatX>,
106    AllocV8: Allocator<v8>,
107    AllocS16: Allocator<s16>,
108    AllocPDF: Allocator<PDF>,
109    AllocStaticCommand: Allocator<StaticCommand>,
110    AllocHistogramLiteral: Allocator<HistogramLiteral>,
111    AllocHistogramCommand: Allocator<HistogramCommand>,
112    AllocHistogramDistance: Allocator<HistogramDistance>,
113    AllocHistogramPair: Allocator<HistogramPair>,
114    AllocContextType: Allocator<ContextType>,
115    AllocHuffmanTree: Allocator<HuffmanTree>,
116    AllocZopfliNode: Allocator<ZopfliNode>,
117>
118    CombiningAllocator<
119        AllocU8,
120        AllocU16,
121        AllocI32,
122        AllocU32,
123        AllocU64,
124        AllocCommand,
125        AllocFloatX,
126        AllocV8,
127        AllocS16,
128        AllocPDF,
129        AllocStaticCommand,
130        AllocHistogramLiteral,
131        AllocHistogramCommand,
132        AllocHistogramDistance,
133        AllocHistogramPair,
134        AllocContextType,
135        AllocHuffmanTree,
136        AllocZopfliNode,
137    >
138{
139    pub fn new(
140        alloc_u8: AllocU8,
141        alloc_u16: AllocU16,
142        alloc_i32: AllocI32,
143        alloc_u32: AllocU32,
144        alloc_u64: AllocU64,
145        alloc_c: AllocCommand,
146        alloc_f: AllocFloatX,
147        alloc_f32x8: AllocV8,
148        alloc_i16x16: AllocS16,
149        alloc_pdf: AllocPDF,
150        alloc_sc: AllocStaticCommand,
151        alloc_hl: AllocHistogramLiteral,
152        alloc_hc: AllocHistogramCommand,
153        alloc_hd: AllocHistogramDistance,
154        alloc_hp: AllocHistogramPair,
155        alloc_ct: AllocContextType,
156        alloc_ht: AllocHuffmanTree,
157        alloc_zn: AllocZopfliNode,
158    ) -> Self {
159        CombiningAllocator {
160            alloc_u8,
161            alloc_u16,
162            alloc_i32,
163            alloc_u32,
164            alloc_u64,
165            alloc_c,
166            alloc_f,
167            alloc_f32x8,
168            alloc_i16x16,
169            alloc_pdf,
170            alloc_sc,
171            alloc_hl,
172            alloc_hc,
173            alloc_hd,
174            alloc_hp,
175            alloc_ct,
176            alloc_ht,
177            alloc_zn,
178        }
179    }
180}
181
182impl<
183    AllocU8: Allocator<u8>,
184    AllocU16: Allocator<u16>,
185    AllocI32: Allocator<i32>,
186    AllocU32: Allocator<u32>,
187    AllocU64: Allocator<u64>,
188    AllocCommand: Allocator<Command>,
189    AllocFloatX: Allocator<floatX>,
190    AllocV8: Allocator<v8>,
191    AllocS16: Allocator<s16>,
192    AllocPDF: Allocator<PDF>,
193    AllocStaticCommand: Allocator<StaticCommand>,
194    AllocHistogramLiteral: Allocator<HistogramLiteral>,
195    AllocHistogramCommand: Allocator<HistogramCommand>,
196    AllocHistogramDistance: Allocator<HistogramDistance>,
197    AllocHistogramPair: Allocator<HistogramPair>,
198    AllocContextType: Allocator<ContextType>,
199    AllocHuffmanTree: Allocator<HuffmanTree>,
200    AllocZopfliNode: Allocator<ZopfliNode>,
201> BrotliAlloc
202    for CombiningAllocator<
203        AllocU8,
204        AllocU16,
205        AllocI32,
206        AllocU32,
207        AllocU64,
208        AllocCommand,
209        AllocFloatX,
210        AllocV8,
211        AllocS16,
212        AllocPDF,
213        AllocStaticCommand,
214        AllocHistogramLiteral,
215        AllocHistogramCommand,
216        AllocHistogramDistance,
217        AllocHistogramPair,
218        AllocContextType,
219        AllocHuffmanTree,
220        AllocZopfliNode,
221    >
222{
223}
224
225impl<
226    AllocU8: Allocator<u8> + Default,
227    AllocU16: Allocator<u16> + Default,
228    AllocI32: Allocator<i32> + Default,
229    AllocU32: Allocator<u32> + Default,
230    AllocU64: Allocator<u64> + Default,
231    AllocCommand: Allocator<Command> + Default,
232    AllocFloatX: Allocator<floatX> + Default,
233    AllocV8: Allocator<v8> + Default,
234    AllocS16: Allocator<s16> + Default,
235    AllocPDF: Allocator<PDF> + Default,
236    AllocStaticCommand: Allocator<StaticCommand> + Default,
237    AllocHistogramLiteral: Allocator<HistogramLiteral> + Default,
238    AllocHistogramCommand: Allocator<HistogramCommand> + Default,
239    AllocHistogramDistance: Allocator<HistogramDistance> + Default,
240    AllocHistogramPair: Allocator<HistogramPair> + Default,
241    AllocContextType: Allocator<ContextType> + Default,
242    AllocHuffmanTree: Allocator<HuffmanTree> + Default,
243    AllocZopfliNode: Allocator<ZopfliNode> + Default,
244> Default
245    for CombiningAllocator<
246        AllocU8,
247        AllocU16,
248        AllocI32,
249        AllocU32,
250        AllocU64,
251        AllocCommand,
252        AllocFloatX,
253        AllocV8,
254        AllocS16,
255        AllocPDF,
256        AllocStaticCommand,
257        AllocHistogramLiteral,
258        AllocHistogramCommand,
259        AllocHistogramDistance,
260        AllocHistogramPair,
261        AllocContextType,
262        AllocHuffmanTree,
263        AllocZopfliNode,
264    >
265{
266    fn default() -> Self {
267        CombiningAllocator {
268            alloc_u8: AllocU8::default(),
269            alloc_u16: AllocU16::default(),
270            alloc_i32: AllocI32::default(),
271            alloc_u32: AllocU32::default(),
272            alloc_u64: AllocU64::default(),
273            alloc_c: AllocCommand::default(),
274            alloc_f: AllocFloatX::default(),
275            alloc_f32x8: AllocV8::default(),
276            alloc_i16x16: AllocS16::default(),
277            alloc_pdf: AllocPDF::default(),
278            alloc_sc: AllocStaticCommand::default(),
279            alloc_hl: AllocHistogramLiteral::default(),
280            alloc_hc: AllocHistogramCommand::default(),
281            alloc_hd: AllocHistogramDistance::default(),
282            alloc_hp: AllocHistogramPair::default(),
283            alloc_ct: AllocContextType::default(),
284            alloc_ht: AllocHuffmanTree::default(),
285            alloc_zn: AllocZopfliNode::default(),
286        }
287    }
288}
289
290impl<
291    AllocU8: Allocator<u8> + Clone,
292    AllocU16: Allocator<u16> + Clone,
293    AllocI32: Allocator<i32> + Clone,
294    AllocU32: Allocator<u32> + Clone,
295    AllocU64: Allocator<u64> + Clone,
296    AllocCommand: Allocator<Command> + Clone,
297    AllocFloatX: Allocator<floatX> + Clone,
298    AllocV8: Allocator<v8> + Clone,
299    AllocS16: Allocator<s16> + Clone,
300    AllocPDF: Allocator<PDF> + Clone,
301    AllocStaticCommand: Allocator<StaticCommand> + Clone,
302    AllocHistogramLiteral: Allocator<HistogramLiteral> + Clone,
303    AllocHistogramCommand: Allocator<HistogramCommand> + Clone,
304    AllocHistogramDistance: Allocator<HistogramDistance> + Clone,
305    AllocHistogramPair: Allocator<HistogramPair> + Clone,
306    AllocContextType: Allocator<ContextType> + Clone,
307    AllocHuffmanTree: Allocator<HuffmanTree> + Clone,
308    AllocZopfliNode: Allocator<ZopfliNode> + Clone,
309> Clone
310    for CombiningAllocator<
311        AllocU8,
312        AllocU16,
313        AllocI32,
314        AllocU32,
315        AllocU64,
316        AllocCommand,
317        AllocFloatX,
318        AllocV8,
319        AllocS16,
320        AllocPDF,
321        AllocStaticCommand,
322        AllocHistogramLiteral,
323        AllocHistogramCommand,
324        AllocHistogramDistance,
325        AllocHistogramPair,
326        AllocContextType,
327        AllocHuffmanTree,
328        AllocZopfliNode,
329    >
330{
331    fn clone(&self) -> Self {
332        CombiningAllocator {
333            alloc_u8: self.alloc_u8.clone(),
334            alloc_u16: self.alloc_u16.clone(),
335            alloc_i32: self.alloc_i32.clone(),
336            alloc_u32: self.alloc_u32.clone(),
337            alloc_u64: self.alloc_u64.clone(),
338            alloc_c: self.alloc_c.clone(),
339            alloc_f: self.alloc_f.clone(),
340            alloc_f32x8: self.alloc_f32x8.clone(),
341            alloc_i16x16: self.alloc_i16x16.clone(),
342            alloc_pdf: self.alloc_pdf.clone(),
343            alloc_sc: self.alloc_sc.clone(),
344            alloc_hl: self.alloc_hl.clone(),
345            alloc_hc: self.alloc_hc.clone(),
346            alloc_hd: self.alloc_hd.clone(),
347            alloc_hp: self.alloc_hp.clone(),
348            alloc_ct: self.alloc_ct.clone(),
349            alloc_ht: self.alloc_ht.clone(),
350            alloc_zn: self.alloc_zn.clone(),
351        }
352    }
353}
354
355impl<
356    AllocU8: Allocator<u8> + Copy,
357    AllocU16: Allocator<u16> + Copy,
358    AllocI32: Allocator<i32> + Copy,
359    AllocU32: Allocator<u32> + Copy,
360    AllocU64: Allocator<u64> + Copy,
361    AllocCommand: Allocator<Command> + Copy,
362    AllocFloatX: Allocator<floatX> + Copy,
363    AllocV8: Allocator<v8> + Copy,
364    AllocS16: Allocator<s16> + Copy,
365    AllocPDF: Allocator<PDF> + Copy,
366    AllocStaticCommand: Allocator<StaticCommand> + Copy,
367    AllocHistogramLiteral: Allocator<HistogramLiteral> + Copy,
368    AllocHistogramCommand: Allocator<HistogramCommand> + Copy,
369    AllocHistogramDistance: Allocator<HistogramDistance> + Copy,
370    AllocHistogramPair: Allocator<HistogramPair> + Copy,
371    AllocContextType: Allocator<ContextType> + Copy,
372    AllocHuffmanTree: Allocator<HuffmanTree> + Copy,
373    AllocZopfliNode: Allocator<ZopfliNode> + Copy,
374> Copy
375    for CombiningAllocator<
376        AllocU8,
377        AllocU16,
378        AllocI32,
379        AllocU32,
380        AllocU64,
381        AllocCommand,
382        AllocFloatX,
383        AllocV8,
384        AllocS16,
385        AllocPDF,
386        AllocStaticCommand,
387        AllocHistogramLiteral,
388        AllocHistogramCommand,
389        AllocHistogramDistance,
390        AllocHistogramPair,
391        AllocContextType,
392        AllocHuffmanTree,
393        AllocZopfliNode,
394    >
395{
396}
397
398macro_rules! implement_allocator {
399    ($bound_name: ty,
400   $type_name: ty,
401   $sub_type_name: ty,
402   $local_name: ident) => {
403        impl<
404            AllocU8: Allocator<u8>,
405            AllocU16: Allocator<u16>,
406            AllocI32: Allocator<i32>,
407            AllocU32: Allocator<u32>,
408            AllocU64: Allocator<u64>,
409            AllocCommand: Allocator<Command>,
410            AllocFloatX: Allocator<floatX>,
411            AllocV8: Allocator<v8>,
412            AllocS16: Allocator<s16>,
413            AllocPDF: Allocator<PDF>,
414            AllocStaticCommand: Allocator<StaticCommand>,
415            AllocHistogramLiteral: Allocator<HistogramLiteral>,
416            AllocHistogramCommand: Allocator<HistogramCommand>,
417            AllocHistogramDistance: Allocator<HistogramDistance>,
418            AllocHistogramPair: Allocator<HistogramPair>,
419            AllocContextType: Allocator<ContextType>,
420            AllocHuffmanTree: Allocator<HuffmanTree>,
421            AllocZopfliNode: Allocator<ZopfliNode>,
422        > Allocator<$type_name>
423            for CombiningAllocator<
424                AllocU8,
425                AllocU16,
426                AllocI32,
427                AllocU32,
428                AllocU64,
429                AllocCommand,
430                AllocFloatX,
431                AllocV8,
432                AllocS16,
433                AllocPDF,
434                AllocStaticCommand,
435                AllocHistogramLiteral,
436                AllocHistogramCommand,
437                AllocHistogramDistance,
438                AllocHistogramPair,
439                AllocContextType,
440                AllocHuffmanTree,
441                AllocZopfliNode,
442            >
443        {
444            type AllocatedMemory = $sub_type_name;
445            fn alloc_cell(
446                &mut self,
447                size: usize,
448            ) -> <Self as Allocator<$type_name>>::AllocatedMemory {
449                self.$local_name.alloc_cell(size)
450            }
451            fn free_cell(&mut self, data: <Self as Allocator<$type_name>>::AllocatedMemory) {
452                self.$local_name.free_cell(data)
453            }
454        }
455    };
456}
457
458implement_allocator!(AllocU8, u8, AllocU8::AllocatedMemory, alloc_u8);
459implement_allocator!(AllocU16, u16, AllocU16::AllocatedMemory, alloc_u16);
460
461implement_allocator!(AllocI32, i32, AllocI32::AllocatedMemory, alloc_i32);
462implement_allocator!(AllocU32, u32, AllocU32::AllocatedMemory, alloc_u32);
463implement_allocator!(AllocU64, u64, AllocU64::AllocatedMemory, alloc_u64);
464implement_allocator!(
465    AllocCommand,
466    Command,
467    AllocCommand::AllocatedMemory,
468    alloc_c
469);
470implement_allocator!(AllocFloatX, floatX, AllocFloatX::AllocatedMemory, alloc_f);
471implement_allocator!(AllocV8, v8, AllocV8::AllocatedMemory, alloc_f32x8);
472implement_allocator!(AllocS16, s16, AllocS16::AllocatedMemory, alloc_i16x16);
473implement_allocator!(AllocPDF, PDF, AllocPDF::AllocatedMemory, alloc_pdf);
474implement_allocator!(
475    AllocStaticCommand,
476    StaticCommand,
477    AllocStaticCommand::AllocatedMemory,
478    alloc_sc
479);
480implement_allocator!(
481    AllocHistogramLiteral,
482    HistogramLiteral,
483    AllocHistogramLiteral::AllocatedMemory,
484    alloc_hl
485);
486implement_allocator!(
487    AllocHistogramCommand,
488    HistogramCommand,
489    AllocHistogramCommand::AllocatedMemory,
490    alloc_hc
491);
492implement_allocator!(
493    AllocHistogramDistance,
494    HistogramDistance,
495    AllocHistogramDistance::AllocatedMemory,
496    alloc_hd
497);
498implement_allocator!(
499    AllocHistogramPair,
500    HistogramPair,
501    AllocHistogramPair::AllocatedMemory,
502    alloc_hp
503);
504implement_allocator!(
505    AllocContextType,
506    ContextType,
507    AllocContextType::AllocatedMemory,
508    alloc_ct
509);
510implement_allocator!(
511    AllocHuffmanTree,
512    HuffmanTree,
513    AllocHuffmanTree::AllocatedMemory,
514    alloc_ht
515);
516implement_allocator!(
517    AllocZopfliNode,
518    ZopfliNode,
519    AllocZopfliNode::AllocatedMemory,
520    alloc_zn
521);
522
523/// Helper function to allocate memory with the given allocator (may crash if the `len` is 0).
524pub(crate) fn allocate<T, A: Allocator<T>>(alloc: &mut A, len: usize) -> A::AllocatedMemory {
525    A::alloc_cell(alloc, len)
526}
527
528/// Helper function to create an empty allocator object
529pub(crate) fn alloc_default<T, A: Allocator<T>>() -> A::AllocatedMemory {
530    A::AllocatedMemory::default()
531}
532
533/// Helper function to allocate memory or return a default value if the condition is false
534pub(crate) fn alloc_if<T, A: Allocator<T>>(
535    condition: bool,
536    alloc: &mut A,
537    len: usize,
538) -> A::AllocatedMemory {
539    if condition {
540        allocate(alloc, len)
541    } else {
542        alloc_default::<T, A>()
543    }
544}
545
546/// Helper function to allocate memory or return a default value when the size is 0.
547pub(crate) fn alloc_or_default<T, A: Allocator<T>>(
548    alloc: &mut A,
549    len: usize,
550) -> A::AllocatedMemory {
551    alloc_if(len > 0, alloc, len)
552}