1 /**
2
3 Collection of typical and useful prebuilt allocators using the given
4 components. User code would typically import this module and use its
5 facilities, or import individual heap building blocks and assemble them.
6
7 */
8 module std.experimental.allocator.showcase;
9
10 import std.experimental.allocator.building_blocks.fallback_allocator,
11 std.experimental.allocator.gc_allocator,
12 std.experimental.allocator.building_blocks.region;
13 import std.traits : hasMember;
14
15 /**
16
17 Allocator that uses stack allocation for up to $(D stackSize) bytes and
18 then falls back to $(D Allocator). Defined as:
19
20 ----
21 alias StackFront(size_t stackSize, Allocator) =
22 FallbackAllocator!(
23 InSituRegion!(stackSize, Allocator.alignment,
24 hasMember!(Allocator, "deallocate")
25 ? Yes.defineDeallocate
26 : No.defineDeallocate),
27 Allocator);
28 ----
29
30 Choosing `stackSize` is as always a compromise. Too small a size exhausts the
31 stack storage after a few allocations, after which there are no gains over the
32 backup allocator. Too large a size increases the stack consumed by the thread
33 and may end up worse off because it explores cold portions of the stack.
34
35 */
36 alias StackFront(size_t stackSize, Allocator = GCAllocator) =
37 FallbackAllocator!(
38 InSituRegion!(stackSize, Allocator.alignment),
39 Allocator);
40
41 ///
42 @system unittest
43 {
44 StackFront!4096 a;
45 auto b = a.allocate(4000);
46 assert(b.length == 4000);
47 auto c = a.allocate(4000);
48 assert(c.length == 4000);
49 a.deallocate(b);
50 a.deallocate(c);
51 }
52
53 /**
54 Creates a scalable `AllocatorList` of `Regions`, each having at least
55 `bytesPerRegion` bytes. Allocation is very fast. This allocator does not offer
56 `deallocate` but does free all regions in its destructor. It is recommended for
57 short-lived batch applications that count on never running out of memory.
58 */
mmapRegionList(size_t bytesPerRegion)59 auto mmapRegionList(size_t bytesPerRegion)
60 {
61 static struct Factory
62 {
63 size_t bytesPerRegion;
64 import std.algorithm.comparison : max;
65 import std.experimental.allocator.building_blocks.region
66 : Region;
67 import std.experimental.allocator.mmap_allocator
68 : MmapAllocator;
69 this(size_t n)
70 {
71 bytesPerRegion = n;
72 }
73 auto opCall(size_t n)
74 {
75 return Region!MmapAllocator(max(n, bytesPerRegion));
76 }
77 }
78 import std.experimental.allocator.building_blocks.allocator_list
79 : AllocatorList;
80 import std.experimental.allocator.building_blocks.null_allocator
81 : NullAllocator;
82 auto shop = Factory(bytesPerRegion);
83 return AllocatorList!(Factory, NullAllocator)(shop);
84 }
85
86 ///
87 @system unittest
88 {
89 auto alloc = mmapRegionList(1024 * 1024);
90 const b = alloc.allocate(100);
91 assert(b.length == 100);
92 }
93