mz_timely_util/
containers.rs

1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License in the LICENSE file at the
6// root of this repository, or online at
7//
8//     http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16//! Reusable containers.
17
18pub mod stack;
19
20pub(crate) use alloc::alloc_aligned_zeroed;
21pub use alloc::{enable_columnar_lgalloc, set_enable_columnar_lgalloc};
22pub use provided_builder::ProvidedBuilder;
23
24mod alloc {
25    use mz_ore::region::Region;
26
27    /// Allocate a region of memory with a capacity of at least `len` that is properly aligned
28    /// and zeroed. The memory in Regions is always aligned to its content type.
29    #[inline]
30    pub(crate) fn alloc_aligned_zeroed<T: bytemuck::AnyBitPattern>(len: usize) -> Region<T> {
31        if enable_columnar_lgalloc() {
32            Region::new_auto_zeroed(len)
33        } else {
34            Region::new_heap_zeroed(len)
35        }
36    }
37
38    thread_local! {
39        static ENABLE_COLUMNAR_LGALLOC: std::cell::Cell<bool> = const { std::cell::Cell::new(false) };
40    }
41
42    /// Returns `true` if columnar allocations should come from lgalloc.
43    #[inline]
44    pub fn enable_columnar_lgalloc() -> bool {
45        ENABLE_COLUMNAR_LGALLOC.get()
46    }
47
48    /// Set whether columnar allocations should come from lgalloc. Applies to future allocations.
49    pub fn set_enable_columnar_lgalloc(enabled: bool) {
50        ENABLE_COLUMNAR_LGALLOC.set(enabled);
51    }
52}
53
54mod provided_builder {
55    use timely::Container;
56    use timely::container::ContainerBuilder;
57
58    /// A container builder that doesn't support pushing elements, and is only suitable for pushing
59    /// whole containers at Timely sessions. See [`give_container`] for more information.
60    ///
61    ///  [`give_container`]: timely::dataflow::channels::pushers::buffer::Session::give_container
62    pub struct ProvidedBuilder<C> {
63        _marker: std::marker::PhantomData<C>,
64    }
65
66    impl<C> Default for ProvidedBuilder<C> {
67        fn default() -> Self {
68            Self {
69                _marker: std::marker::PhantomData,
70            }
71        }
72    }
73
74    impl<C: Container + Clone + 'static> ContainerBuilder for ProvidedBuilder<C> {
75        type Container = C;
76
77        #[inline(always)]
78        fn extract(&mut self) -> Option<&mut Self::Container> {
79            None
80        }
81
82        #[inline(always)]
83        fn finish(&mut self) -> Option<&mut Self::Container> {
84            None
85        }
86    }
87}