Skip to content

Commit 691f70d

Browse files
authored
Merge pull request #2299 from Veeupup/session_mem_alloctor
add mem alloc and derive macro
2 parents c46983f + 6559eca commit 691f70d

File tree

19 files changed

+1347
-8
lines changed

19 files changed

+1347
-8
lines changed

Cargo.lock

+40
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ members = [
1616
"common/infallible",
1717
"common/io",
1818
"common/management",
19+
"common/mem/mem-allocator",
20+
"common/mem/mem-derive",
1921
"common/planners",
2022
"common/meta/api",
2123
"common/meta/embedded",

common/datavalues/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ edition = "2021"
1111
common-arrow = {path = "../arrow"}
1212
common-exception = {path = "../exception"}
1313
common-io = {path = "../io"}
14+
common-mem-derive = {path = "../mem/mem-derive"}
15+
common-mem-allocator = {path = "../mem/mem-allocator"}
1416

1517
# Github dependencies
1618

common/datavalues/src/data_field.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,21 @@
1515
use std::collections::BTreeMap;
1616

1717
use common_arrow::arrow::datatypes::Field as ArrowField;
18+
use common_mem_derive::*;
1819

1920
use crate::DataType;
2021

2122
#[derive(
22-
serde::Serialize, serde::Deserialize, Clone, Debug, PartialEq, Hash, Eq, PartialOrd, Ord,
23+
serde::Serialize,
24+
serde::Deserialize,
25+
Clone,
26+
Debug,
27+
PartialEq,
28+
Hash,
29+
Eq,
30+
PartialOrd,
31+
Ord,
32+
MallocSizeOf,
2333
)]
2434
pub struct DataField {
2535
name: String,

common/datavalues/src/data_value.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use common_arrow::arrow::datatypes::Field as ArrowField;
2525
use common_exception::ErrorCode;
2626
use common_exception::Result;
2727
use common_io::prelude::*;
28+
use common_mem_derive::*;
2829

2930
use crate::arrays::ListBooleanArrayBuilder;
3031
use crate::arrays::ListBuilderTrait;
@@ -36,7 +37,7 @@ use crate::series::Series;
3637
use crate::DataField;
3738

3839
/// A specific value of a data type.
39-
#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq)]
40+
#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, MallocSizeOf)]
4041
pub enum DataValue {
4142
/// Base type.
4243
Null,

common/datavalues/src/types/data_type.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,14 @@
1515
use core::fmt;
1616

1717
use common_arrow::arrow::datatypes::DataType as ArrowDataType;
18+
use common_mem_derive::*;
1819

1920
use crate::DataField;
2021
use crate::PhysicalDataType;
2122

22-
#[derive(serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
23+
#[derive(
24+
serde::Serialize, serde::Deserialize, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, MallocSizeOf,
25+
)]
2326
pub enum DataType {
2427
Null,
2528
Boolean,
@@ -53,7 +56,16 @@ pub enum DataType {
5356
}
5457

5558
#[derive(
56-
serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord,
59+
serde::Serialize,
60+
serde::Deserialize,
61+
Debug,
62+
Clone,
63+
PartialEq,
64+
Eq,
65+
Hash,
66+
PartialOrd,
67+
Ord,
68+
MallocSizeOf,
5769
)]
5870
pub enum IntervalUnit {
5971
YearMonth,

common/mem/mem-allocator/Cargo.toml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[package]
2+
name = "common-mem-allocator"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
tikv-jemalloc-sys = "0.4.2+5.2.1-patched.2"
10+
common-infallible = { path = "../../infallible" }
11+
parking_lot = "0.11"
12+
common-mem-derive = { path = "../mem-derive" }
+153
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
// Copyright 2020 Datafuse Labs.
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 at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
use crate::malloc_size::MallocSizeOf;
16+
use crate::malloc_size::MallocSizeOfOps;
17+
use crate::malloc_size::MallocUnconditionalSizeOf;
18+
19+
/* This Source Code Form is subject to the terms of the Mozilla Public
20+
* License, v. 2.0. If a copy of the MPL was not distributed with this
21+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
22+
23+
#[global_allocator]
24+
static ALLOC: Allocator = Allocator;
25+
26+
pub use platform::*;
27+
pub use tikv_jemalloc_sys;
28+
29+
mod platform {
30+
use std::alloc::GlobalAlloc;
31+
use std::alloc::Layout;
32+
use std::os::raw::c_int;
33+
use std::os::raw::c_void;
34+
35+
use tikv_jemalloc_sys as ffi;
36+
37+
use crate::malloc_size::VoidPtrToSizeFn;
38+
39+
/// Get the size of a heap block.
40+
pub unsafe extern "C" fn usable_size(ptr: *const c_void) -> usize {
41+
ffi::malloc_usable_size(ptr as *const _)
42+
}
43+
44+
/// No enclosing function defined.
45+
#[inline]
46+
pub fn new_enclosing_size_fn() -> Option<VoidPtrToSizeFn> {
47+
None
48+
}
49+
50+
/// Memory allocation APIs compatible with libc
51+
pub mod libc_compat {
52+
pub use super::ffi::free;
53+
pub use super::ffi::malloc;
54+
pub use super::ffi::realloc;
55+
}
56+
57+
pub struct Allocator;
58+
59+
// The minimum alignment guaranteed by the architecture. This value is used to
60+
// add fast paths for low alignment values.
61+
#[cfg(all(any(
62+
target_arch = "arm",
63+
target_arch = "mips",
64+
target_arch = "mipsel",
65+
target_arch = "powerpc"
66+
)))]
67+
const MIN_ALIGN: usize = 8;
68+
#[cfg(all(any(
69+
target_arch = "x86",
70+
target_arch = "x86_64",
71+
target_arch = "aarch64",
72+
target_arch = "powerpc64",
73+
target_arch = "powerpc64le",
74+
target_arch = "mips64",
75+
target_arch = "s390x",
76+
target_arch = "sparc64"
77+
)))]
78+
const MIN_ALIGN: usize = 16;
79+
80+
fn layout_to_flags(align: usize, size: usize) -> c_int {
81+
// If our alignment is less than the minimum alignment they we may not
82+
// have to pass special flags asking for a higher alignment. If the
83+
// alignment is greater than the size, however, then this hits a sort of odd
84+
// case where we still need to ask for a custom alignment. See #25 for more
85+
// info.
86+
if align <= MIN_ALIGN && align <= size {
87+
0
88+
} else {
89+
// Equivalent to the MALLOCX_ALIGN(a) macro.
90+
align.trailing_zeros() as _
91+
}
92+
}
93+
94+
unsafe impl GlobalAlloc for Allocator {
95+
#[inline]
96+
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
97+
let flags = layout_to_flags(layout.align(), layout.size());
98+
ffi::mallocx(layout.size(), flags) as *mut u8
99+
}
100+
101+
#[inline]
102+
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
103+
if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
104+
ffi::calloc(1, layout.size()) as *mut u8
105+
} else {
106+
let flags = layout_to_flags(layout.align(), layout.size()) | ffi::MALLOCX_ZERO;
107+
ffi::mallocx(layout.size(), flags) as *mut u8
108+
}
109+
}
110+
111+
#[inline]
112+
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
113+
let flags = layout_to_flags(layout.align(), layout.size());
114+
ffi::sdallocx(ptr as *mut _, layout.size(), flags)
115+
}
116+
117+
#[inline]
118+
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
119+
let flags = layout_to_flags(layout.align(), new_size);
120+
ffi::rallocx(ptr as *mut _, new_size, flags) as *mut u8
121+
}
122+
}
123+
}
124+
125+
/// Get a new instance of a MallocSizeOfOps
126+
pub fn new_malloc_size_ops() -> MallocSizeOfOps {
127+
MallocSizeOfOps::new(
128+
platform::usable_size,
129+
platform::new_enclosing_size_fn(),
130+
None,
131+
)
132+
}
133+
134+
/// Extension methods for `MallocSizeOf` trait, do not implement
135+
/// directly.
136+
/// It allows getting heapsize without exposing `MallocSizeOfOps`
137+
/// (a single default `MallocSizeOfOps` is used for each call).
138+
pub trait MallocSizeOfExt: MallocSizeOf {
139+
/// Method to launch a heapsize measurement with a
140+
/// fresh state.
141+
fn malloc_size_of(&self) -> usize {
142+
let mut ops = new_malloc_size_ops();
143+
<Self as MallocSizeOf>::size_of(self, &mut ops)
144+
}
145+
}
146+
147+
impl<T: MallocSizeOf> MallocSizeOfExt for T {}
148+
149+
impl<T: MallocSizeOf> MallocSizeOf for std::sync::Arc<T> {
150+
fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize {
151+
self.unconditional_size_of(ops)
152+
}
153+
}

common/mem/mem-allocator/src/lib.rs

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2020 Datafuse Labs.
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 at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
mod allocators;
16+
mod malloc_size;
17+
// mod sizeof;
18+
19+
pub use allocators::MallocSizeOfExt;
20+
pub use malloc_size::MallocShallowSizeOf;
21+
pub use malloc_size::MallocSizeOf;
22+
pub use malloc_size::MallocSizeOfOps;
23+
24+
/// Heap size of structure.
25+
///
26+
/// Structure can be anything that implements MallocSizeOf.
27+
pub fn malloc_size<T: MallocSizeOf + ?Sized>(t: &T) -> usize {
28+
MallocSizeOf::size_of(t, &mut allocators::new_malloc_size_ops())
29+
}

0 commit comments

Comments
 (0)