]> git.donarmstrong.com Git - bamtools.git/blob - src/api/internal/BamMultiMerger_p.h
Removed 'core mode' concept from BamMultiReader internals
[bamtools.git] / src / api / internal / BamMultiMerger_p.h
1 // ***************************************************************************
2 // BamMultiMerger_p.h (c) 2010 Derek Barnett
3 // Marth Lab, Department of Biology, Boston College
4 // All rights reserved.
5 // ---------------------------------------------------------------------------
6 // Last modified: 9 September 2011 (DB)
7 // ---------------------------------------------------------------------------
8 // Provides merging functionality for BamMultiReader.  At this point, supports
9 // sorting results by (refId, position) or by read name.
10 // ***************************************************************************
11
12 #ifndef BAMMULTIMERGER_P_H
13 #define BAMMULTIMERGER_P_H
14
15 //  -------------
16 //  W A R N I N G
17 //  -------------
18 //
19 // This file is not part of the BamTools API.  It exists purely as an
20 // implementation detail. This header file may change from version to version
21 // without notice, or even be removed.
22 //
23 // We mean it.
24
25 #include <api/BamAlignment.h>
26 #include <api/BamReader.h>
27 #include <map>
28 #include <queue>
29 #include <string>
30 #include <utility>
31
32 namespace BamTools {
33 namespace Internal {
34
35 typedef std::pair<BamReader*, BamAlignment*> ReaderAlignment;
36
37 // generic MultiMerger interface
38 class IBamMultiMerger {
39
40     public:
41         IBamMultiMerger(void) { }
42         virtual ~IBamMultiMerger(void) { }
43
44     public:
45         virtual void Add(ReaderAlignment value) =0;
46         virtual void Clear(void) =0;
47         virtual const ReaderAlignment& First(void) const =0;
48         virtual bool IsEmpty(void) const =0;
49         virtual void Remove(BamReader* reader) =0;
50         virtual int Size(void) const =0;
51         virtual ReaderAlignment TakeFirst(void) =0;
52 };
53
54 // IBamMultiMerger implementation - sorted on BamAlignment: (RefId, Position)
55 class PositionMultiMerger : public IBamMultiMerger {
56
57     public:
58         PositionMultiMerger(void) : IBamMultiMerger() { }
59         ~PositionMultiMerger(void) { }
60
61     public:
62         void Add(ReaderAlignment value);
63         void Clear(void);
64         const ReaderAlignment& First(void) const;
65         bool IsEmpty(void) const;
66         void Remove(BamReader* reader);
67         int Size(void) const;
68         ReaderAlignment TakeFirst(void);
69
70     private:
71         typedef std::pair<int, int>           KeyType;
72         typedef ReaderAlignment               ValueType;
73         typedef std::pair<KeyType, ValueType> ElementType;
74
75         typedef std::multimap<KeyType, ValueType> ContainerType;
76         typedef ContainerType::iterator           DataIterator;
77         typedef ContainerType::const_iterator     DataConstIterator;
78
79         ContainerType m_data;
80 };
81
82 // IBamMultiMerger implementation - sorted on BamAlignment: Name
83 class ReadNameMultiMerger : public IBamMultiMerger {
84
85     public:
86         ReadNameMultiMerger(void) : IBamMultiMerger() { }
87         ~ReadNameMultiMerger(void) { }
88
89     public:
90         void Add(ReaderAlignment value);
91         void Clear(void);
92         const ReaderAlignment& First(void) const;
93         bool IsEmpty(void) const;
94         void Remove(BamReader* reader);
95         int Size(void) const;
96         ReaderAlignment TakeFirst(void);
97
98     private:
99         typedef std::string                   KeyType;
100         typedef ReaderAlignment               ValueType;
101         typedef std::pair<KeyType, ValueType> ElementType;
102
103         typedef std::multimap<KeyType, ValueType> ContainerType;
104         typedef ContainerType::iterator           DataIterator;
105         typedef ContainerType::const_iterator     DataConstIterator;
106
107         ContainerType m_data;
108 };
109
110 // IBamMultiMerger implementation - unsorted BAM file(s)
111 class UnsortedMultiMerger : public IBamMultiMerger {
112
113     public:
114         UnsortedMultiMerger(void) : IBamMultiMerger() { }
115         ~UnsortedMultiMerger(void) { }
116
117     public:
118         void Add(ReaderAlignment value);
119         void Clear(void);
120         const ReaderAlignment& First(void) const;
121         bool IsEmpty(void) const;
122         void Remove(BamReader* reader);
123         int Size(void) const;
124         ReaderAlignment TakeFirst(void);
125
126     private:
127         typedef ReaderAlignment ElementType;
128         typedef std::vector<ReaderAlignment>  ContainerType;
129         typedef ContainerType::iterator       DataIterator;
130         typedef ContainerType::const_iterator DataConstIterator;
131
132         ContainerType m_data;
133 };
134
135 // ------------------------------------------
136 // PositionMultiMerger implementation
137
138 inline void PositionMultiMerger::Add(ReaderAlignment value) {
139     const KeyType key( value.second->RefID, value.second->Position );
140     m_data.insert( ElementType(key, value) );
141 }
142
143 inline void PositionMultiMerger::Clear(void) {
144     m_data.clear();
145 }
146
147 inline const ReaderAlignment& PositionMultiMerger::First(void) const {
148     const ElementType& entry = (*m_data.begin());
149     return entry.second;
150 }
151
152 inline bool PositionMultiMerger::IsEmpty(void) const {
153     return m_data.empty();
154 }
155
156 inline void PositionMultiMerger::Remove(BamReader* reader) {
157
158     if ( reader == 0 ) return;
159     const std::string filenameToRemove = reader->GetFilename();
160
161     // iterate over readers in cache
162     DataIterator dataIter = m_data.begin();
163     DataIterator dataEnd  = m_data.end();
164     for ( ; dataIter != dataEnd; ++dataIter ) {
165         const ValueType& entry = (*dataIter).second;
166         const BamReader* entryReader = entry.first;
167         if ( entryReader == 0 ) continue;
168
169         // remove iterator on match
170         if ( entryReader->GetFilename() == filenameToRemove ) {
171             m_data.erase(dataIter);
172             return;
173         }
174     }
175 }
176
177 inline int PositionMultiMerger::Size(void) const {
178     return m_data.size();
179 }
180
181 inline ReaderAlignment PositionMultiMerger::TakeFirst(void) {
182     DataIterator first = m_data.begin();
183     ReaderAlignment next = (*first).second;
184     m_data.erase(first);
185     return next;
186 }
187
188 // ------------------------------------------
189 // ReadNameMultiMerger implementation
190
191 inline void ReadNameMultiMerger::Add(ReaderAlignment value) {
192     BamAlignment* al = value.second;
193     if ( al->BuildCharData() ) {
194         const KeyType key(al->Name);
195         m_data.insert( ElementType(key, value) );
196     }
197 }
198
199 inline void ReadNameMultiMerger::Clear(void) {
200     m_data.clear();
201 }
202
203 inline const ReaderAlignment& ReadNameMultiMerger::First(void) const {
204     const ElementType& entry = (*m_data.begin());
205     return entry.second;
206 }
207
208 inline bool ReadNameMultiMerger::IsEmpty(void) const {
209     return m_data.empty();
210 }
211
212 inline void ReadNameMultiMerger::Remove(BamReader* reader) {
213
214     if ( reader == 0 ) return;
215     const std::string filenameToRemove = reader->GetFilename();
216
217     // iterate over readers in cache
218     DataIterator dataIter = m_data.begin();
219     DataIterator dataEnd  = m_data.end();
220     for ( ; dataIter != dataEnd; ++dataIter ) {
221         const ValueType& entry = (*dataIter).second;
222         const BamReader* entryReader = entry.first;
223         if ( entryReader == 0 ) continue;
224
225         // remove iterator on match
226         if ( entryReader->GetFilename() == filenameToRemove ) {
227             m_data.erase(dataIter);
228             return;
229         }
230     }
231
232 }
233
234 inline int ReadNameMultiMerger::Size(void) const {
235     return m_data.size();
236 }
237
238 inline ReaderAlignment ReadNameMultiMerger::TakeFirst(void) {
239     DataIterator first = m_data.begin();
240     ReaderAlignment next = (*first).second;
241     m_data.erase(first);
242     return next;
243 }
244
245 // ------------------------------------------
246 // UnsortedMultiMerger implementation
247
248 inline void UnsortedMultiMerger::Add(ReaderAlignment value) {
249     m_data.push_back(value);
250 }
251
252 inline void UnsortedMultiMerger::Clear(void) {
253     for (size_t i = 0; i < m_data.size(); ++i )
254         m_data.pop_back();
255 }
256
257 inline const ReaderAlignment& UnsortedMultiMerger::First(void) const {
258     return m_data.front();
259 }
260
261 inline bool UnsortedMultiMerger::IsEmpty(void) const {
262     return m_data.empty();
263 }
264
265 inline void UnsortedMultiMerger::Remove(BamReader* reader) {
266
267     if ( reader == 0 ) return;
268     const std::string filenameToRemove = reader->GetFilename();
269
270     // iterate over readers in cache
271     DataIterator dataIter = m_data.begin();
272     DataIterator dataEnd  = m_data.end();
273     for ( ; dataIter != dataEnd; ++dataIter ) {
274         const BamReader* entryReader = (*dataIter).first;
275         if ( entryReader == 0 ) continue;
276
277         // remove iterator on match
278         if ( entryReader->GetFilename() == filenameToRemove ) {
279             m_data.erase(dataIter);
280             return;
281         }
282     }
283 }
284
285 inline int UnsortedMultiMerger::Size(void) const {
286     return m_data.size();
287 }
288
289 inline ReaderAlignment UnsortedMultiMerger::TakeFirst(void) {
290     ReaderAlignment first = m_data.front();
291     m_data.erase( m_data.begin() );
292     return first;
293 }
294
295 } // namespace Internal
296 } // namespace BamTools
297
298 #endif // BAMMULTIMERGER_P_H