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