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: 18 March 2011 (DB)
7 // ---------------------------------------------------------------------------
8 // Provides merging functionality for BamMultiReader. At this point, supports
9 // sorting results by (refId, position) or by read name.
10 // ***************************************************************************
12 #ifndef BAMMULTIMERGER_P_H
13 #define BAMMULTIMERGER_P_H
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.
25 #include <api/BamAlignment.h>
26 #include <api/BamReader.h>
35 typedef std::pair<BamReader*, BamAlignment*> ReaderAlignment;
37 // generic MultiMerger interface
38 class IBamMultiMerger {
41 IBamMultiMerger(void) { }
42 virtual ~IBamMultiMerger(void) { }
45 virtual void Add(const 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;
54 // IBamMultiMerger implementation - sorted on BamAlignment: (RefId, Position)
55 class PositionMultiMerger : public IBamMultiMerger {
58 PositionMultiMerger(void) : IBamMultiMerger() { }
59 ~PositionMultiMerger(void) { }
62 void Add(const ReaderAlignment& value);
64 const ReaderAlignment& First(void) const;
65 bool IsEmpty(void) const;
66 void Remove(BamReader* reader);
68 ReaderAlignment TakeFirst(void);
71 typedef std::pair<int, int> KeyType;
72 typedef ReaderAlignment ValueType;
73 typedef std::pair<KeyType, ValueType> ElementType;
75 typedef std::multimap<KeyType, ValueType> ContainerType;
76 typedef ContainerType::iterator DataIterator;
77 typedef ContainerType::const_iterator DataConstIterator;
82 // IBamMultiMerger implementation - sorted on BamAlignment: Name
83 class ReadNameMultiMerger : public IBamMultiMerger {
86 ReadNameMultiMerger(void) : IBamMultiMerger() { }
87 ~ReadNameMultiMerger(void) { }
90 void Add(const ReaderAlignment& value);
92 const ReaderAlignment& First(void) const;
93 bool IsEmpty(void) const;
94 void Remove(BamReader* reader);
96 ReaderAlignment TakeFirst(void);
99 typedef std::string KeyType;
100 typedef ReaderAlignment ValueType;
101 typedef std::pair<KeyType, ValueType> ElementType;
103 typedef std::multimap<KeyType, ValueType> ContainerType;
104 typedef ContainerType::iterator DataIterator;
105 typedef ContainerType::const_iterator DataConstIterator;
107 ContainerType m_data;
110 // IBamMultiMerger implementation - unsorted BAM file(s)
111 class UnsortedMultiMerger : public IBamMultiMerger {
114 UnsortedMultiMerger(void) : IBamMultiMerger() { }
115 ~UnsortedMultiMerger(void) { }
118 void Add(const ReaderAlignment& value);
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);
127 typedef ReaderAlignment ElementType;
128 typedef std::vector<ReaderAlignment> ContainerType;
129 typedef ContainerType::iterator DataIterator;
130 typedef ContainerType::const_iterator DataConstIterator;
132 ContainerType m_data;
135 // ------------------------------------------
136 // PositionMultiMerger implementation
138 inline void PositionMultiMerger::Add(const ReaderAlignment& value) {
139 const KeyType key( value.second->RefID, value.second->Position );
140 m_data.insert( ElementType(key, value) );
143 inline void PositionMultiMerger::Clear(void) {
147 inline const ReaderAlignment& PositionMultiMerger::First(void) const {
148 const ElementType& entry = (*m_data.begin());
152 inline bool PositionMultiMerger::IsEmpty(void) const {
153 return m_data.empty();
156 inline void PositionMultiMerger::Remove(BamReader* reader) {
158 if ( reader == 0 ) return;
159 const std::string filenameToRemove = reader->GetFilename();
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;
169 // remove iterator on match
170 if ( entryReader->GetFilename() == filenameToRemove ) {
171 m_data.erase(dataIter);
177 inline int PositionMultiMerger::Size(void) const {
178 return m_data.size();
181 inline ReaderAlignment PositionMultiMerger::TakeFirst(void) {
182 DataIterator first = m_data.begin();
183 ReaderAlignment next = (*first).second;
188 // ------------------------------------------
189 // ReadNameMultiMerger implementation
191 inline void ReadNameMultiMerger::Add(const ReaderAlignment& value) {
192 const KeyType key(value.second->Name);
193 m_data.insert( ElementType(key, value) );
196 inline void ReadNameMultiMerger::Clear(void) {
200 inline const ReaderAlignment& ReadNameMultiMerger::First(void) const {
201 const ElementType& entry = (*m_data.begin());
205 inline bool ReadNameMultiMerger::IsEmpty(void) const {
206 return m_data.empty();
209 inline void ReadNameMultiMerger::Remove(BamReader* reader) {
211 if ( reader == 0 ) return;
212 const std::string filenameToRemove = reader->GetFilename();
214 // iterate over readers in cache
215 DataIterator dataIter = m_data.begin();
216 DataIterator dataEnd = m_data.end();
217 for ( ; dataIter != dataEnd; ++dataIter ) {
218 const ValueType& entry = (*dataIter).second;
219 const BamReader* entryReader = entry.first;
220 if ( entryReader == 0 ) continue;
222 // remove iterator on match
223 if ( entryReader->GetFilename() == filenameToRemove ) {
224 m_data.erase(dataIter);
231 inline int ReadNameMultiMerger::Size(void) const {
232 return m_data.size();
235 inline ReaderAlignment ReadNameMultiMerger::TakeFirst(void) {
236 DataIterator first = m_data.begin();
237 ReaderAlignment next = (*first).second;
242 // ------------------------------------------
243 // UnsortedMultiMerger implementation
245 inline void UnsortedMultiMerger::Add(const ReaderAlignment& value) {
246 m_data.push_back(value);
249 inline void UnsortedMultiMerger::Clear(void) {
250 for (size_t i = 0; i < m_data.size(); ++i )
254 inline const ReaderAlignment& UnsortedMultiMerger::First(void) const {
255 return m_data.front();
258 inline bool UnsortedMultiMerger::IsEmpty(void) const {
259 return m_data.empty();
262 inline void UnsortedMultiMerger::Remove(BamReader* reader) {
264 if ( reader == 0 ) return;
265 const std::string filenameToRemove = reader->GetFilename();
267 // iterate over readers in cache
268 DataIterator dataIter = m_data.begin();
269 DataIterator dataEnd = m_data.end();
270 for ( ; dataIter != dataEnd; ++dataIter ) {
271 const BamReader* entryReader = (*dataIter).first;
272 if ( entryReader == 0 ) continue;
274 // remove iterator on match
275 if ( entryReader->GetFilename() == filenameToRemove ) {
276 m_data.erase(dataIter);
282 inline int UnsortedMultiMerger::Size(void) const {
283 return m_data.size();
286 inline ReaderAlignment UnsortedMultiMerger::TakeFirst(void) {
287 ReaderAlignment first = m_data.front();
288 m_data.erase( m_data.begin() );
292 } // namespace Internal
293 } // namespace BamTools
295 #endif // BAMMULTIMERGER_P_H