1 /*==========================================================================
2 SeqAn - The Library for Sequence Analysis
4 ============================================================================
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 3 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 ============================================================================
18 $Id: basic_allocator_simple.h,v 1.1 2008/08/25 16:20:02 langmead Exp $
19 ==========================================================================*/
21 #ifndef SEQAN_HEADER_BASIC_ALLOCATOR_SIMPLE_H
22 #define SEQAN_HEADER_BASIC_ALLOCATOR_SIMPLE_H
24 namespace SEQAN_NAMESPACE_MAIN
26 //////////////////////////////////////////////////////////////////////////////
29 //////////////////////////////////////////////////////////////////////////////
30 // SimpleAlloc Allocator
31 //////////////////////////////////////////////////////////////////////////////
34 .Spec.Simple Allocator:
36 ..general:Class.Allocator
37 ..summary:General purpose allocator.
38 ..signature:Allocator< SimpleAlloc<ParentAllocator> >
39 ..param.ParentAllocator:An allocator that is by the simple allocator used to allocate memory.
40 ...default:@Tag.Default@
41 ...remarks:@Tag.Default@ used as allocator means that the default implementations
42 of @Function.allocate@ and @Function.deallocate@ are used.
45 template <typename TParentAllocator = Default>
48 //////////////////////////////////////////////////////////////////////////////
51 typedef Allocator<SimpleAlloc<Default> > SimpleAllocator;
53 template <typename TParentAllocator>
54 struct Allocator<SimpleAlloc<TParentAllocator> >
63 Header * data_storages;
64 Holder<TParentAllocator> data_parent_allocator;
72 Allocator(TParentAllocator & parent_alloc):
76 setValue(data_parent_allocator, parent_alloc);
80 Allocator(Allocator const &):
85 operator = (Allocator const &)
98 //////////////////////////////////////////////////////////////////////////////
100 template <typename TParentAllocator>
101 inline TParentAllocator &
102 parentAllocator(Allocator<SimpleAlloc<TParentAllocator> > & me)
105 return value(me.data_parent_allocator);
108 //////////////////////////////////////////////////////////////////////////////
110 .Function.Allocator#clear:
112 ..summary:Deallocates all memory blocks.
113 ..signature:clear(allocator)
114 ..param.allocator:Allocator object.
115 ...type:Class.Allocator
116 ...concept:Concept.Allocator
117 ..remarks:This function deallocates all memory blocks
118 that was allocated using @Function.allocate@ for $allocator$.
119 The memory is not pooled but directly passed back to the heap manager.
120 ..see:Function.allocate
121 ..see:Function.deallocate
123 template <typename TParentAllocator>
125 clear(Allocator<SimpleAlloc<TParentAllocator> > & me)
128 typedef Allocator<SimpleAlloc<TParentAllocator> > TAllocator;
130 while (me.data_storages)
132 typename TAllocator::Header * next_storage = me.data_storages->right;
133 deallocate(parentAllocator(me), reinterpret_cast<char *>(me.data_storages), me.data_storages->size);
134 me.data_storages = next_storage;
138 //////////////////////////////////////////////////////////////////////////////
140 template <typename TParentAllocator, typename TValue, typename TSize, typename TUsage>
142 allocate(Allocator<SimpleAlloc<TParentAllocator> > & me,
148 typedef Allocator<SimpleAlloc<TParentAllocator> > TAllocator;
149 typedef typename TAllocator::Header THeader;
151 //compute needed bytes
152 size_t bytes_needed = count * sizeof(TValue) + sizeof(THeader);
154 //allocate storage from parent
156 allocate(parentAllocator(me), ptr, bytes_needed, TagAllocateStorage());
158 THeader * new_block = reinterpret_cast<THeader *>(ptr);
160 new_block->right = me.data_storages;
161 new_block->size = bytes_needed;
163 if (me.data_storages)
165 me.data_storages->left = new_block;
167 me.data_storages = new_block;
170 data = reinterpret_cast<TValue *>(ptr + sizeof(THeader));
173 //////////////////////////////////////////////////////////////////////////////
175 template <typename TParentAllocator, typename TValue, typename TSize, typename TUsage>
177 deallocate(Allocator<SimpleAlloc<TParentAllocator> > & me,
183 typedef Allocator<SimpleAlloc<TParentAllocator> > TAllocator;
184 typedef typename TAllocator::Header THeader;
187 THeader & header = *(reinterpret_cast<THeader *>(data) - 1);
190 header.left->right = header.right;
194 me.data_storages = header.right;
198 header.right->left = header.left;
201 //deallocate storage using parent
202 char * ptr = reinterpret_cast<char *>(& header);
203 deallocate(parentAllocator(me), ptr, header.size);
206 //////////////////////////////////////////////////////////////////////////////
208 } //namespace SEQAN_NAMESPACE_MAIN
210 #endif //#ifndef SEQAN_HEADER_...