1 // ***************************************************************************
2 // BamMultiMerger_p.h (c) 2010 Derek Barnett
3 // Marth Lab, Department of Biology, Boston College
4 // ---------------------------------------------------------------------------
5 // Last modified: 9 September 2011 (DB)
6 // ---------------------------------------------------------------------------
7 // Provides merging functionality for BamMultiReader. At this point, supports
8 // sorting results by (refId, position) or by read name.
9 // ***************************************************************************
11 #ifndef BAMMULTIMERGER_P_H
12 #define BAMMULTIMERGER_P_H
18 // This file is not part of the BamTools API. It exists purely as an
19 // implementation detail. This header file may change from version to version
20 // without notice, or even be removed.
24 #include <api/BamAlignment.h>
25 #include <api/BamReader.h>
34 typedef std::pair<BamReader*, BamAlignment*> ReaderAlignment;
36 // generic MultiMerger interface
37 class IBamMultiMerger {
40 IBamMultiMerger(void) { }
41 virtual ~IBamMultiMerger(void) { }
44 virtual void Add(ReaderAlignment value) =0;
45 virtual void Clear(void) =0;
46 virtual const ReaderAlignment& First(void) const =0;
47 virtual bool IsEmpty(void) const =0;
48 virtual void Remove(BamReader* reader) =0;
49 virtual int Size(void) const =0;
50 virtual ReaderAlignment TakeFirst(void) =0;
53 // IBamMultiMerger implementation - sorted on BamAlignment: (RefId, Position)
54 class PositionMultiMerger : public IBamMultiMerger {
57 PositionMultiMerger(void) : IBamMultiMerger() { }
58 ~PositionMultiMerger(void) { }
61 void Add(ReaderAlignment value);
63 const ReaderAlignment& First(void) const;
64 bool IsEmpty(void) const;
65 void Remove(BamReader* reader);
67 ReaderAlignment TakeFirst(void);
70 typedef std::pair<int, int> KeyType;
71 typedef ReaderAlignment ValueType;
72 typedef std::pair<KeyType, ValueType> ElementType;
74 typedef std::multimap<KeyType, ValueType> ContainerType;
75 typedef ContainerType::iterator DataIterator;
76 typedef ContainerType::const_iterator DataConstIterator;
81 // IBamMultiMerger implementation - sorted on BamAlignment: Name
82 class ReadNameMultiMerger : public IBamMultiMerger {
85 ReadNameMultiMerger(void) : IBamMultiMerger() { }
86 ~ReadNameMultiMerger(void) { }
89 void Add(ReaderAlignment value);
91 const ReaderAlignment& First(void) const;
92 bool IsEmpty(void) const;
93 void Remove(BamReader* reader);
95 ReaderAlignment TakeFirst(void);
98 typedef std::string KeyType;
99 typedef ReaderAlignment ValueType;
100 typedef std::pair<KeyType, ValueType> ElementType;
102 typedef std::multimap<KeyType, ValueType> ContainerType;
103 typedef ContainerType::iterator DataIterator;
104 typedef ContainerType::const_iterator DataConstIterator;
106 ContainerType m_data;
109 // IBamMultiMerger implementation - unsorted BAM file(s)
110 class UnsortedMultiMerger : public IBamMultiMerger {
113 UnsortedMultiMerger(void) : IBamMultiMerger() { }
114 ~UnsortedMultiMerger(void) { }
117 void Add(ReaderAlignment value);
119 const ReaderAlignment& First(void) const;
120 bool IsEmpty(void) const;
121 void Remove(BamReader* reader);
122 int Size(void) const;
123 ReaderAlignment TakeFirst(void);
126 typedef ReaderAlignment ElementType;
127 typedef std::vector<ReaderAlignment> ContainerType;
128 typedef ContainerType::iterator DataIterator;
129 typedef ContainerType::const_iterator DataConstIterator;
131 ContainerType m_data;
134 // ------------------------------------------
135 // PositionMultiMerger implementation
137 inline void PositionMultiMerger::Add(ReaderAlignment value) {
138 const KeyType key( value.second->RefID, value.second->Position );
139 m_data.insert( ElementType(key, value) );
142 inline void PositionMultiMerger::Clear(void) {
146 inline const ReaderAlignment& PositionMultiMerger::First(void) const {
147 const ElementType& entry = (*m_data.begin());
151 inline bool PositionMultiMerger::IsEmpty(void) const {
152 return m_data.empty();
155 inline void PositionMultiMerger::Remove(BamReader* reader) {
157 if ( reader == 0 ) return;
158 const std::string filenameToRemove = reader->GetFilename();
160 // iterate over readers in cache
161 DataIterator dataIter = m_data.begin();
162 DataIterator dataEnd = m_data.end();
163 for ( ; dataIter != dataEnd; ++dataIter ) {
164 const ValueType& entry = (*dataIter).second;
165 const BamReader* entryReader = entry.first;
166 if ( entryReader == 0 ) continue;
168 // remove iterator on match
169 if ( entryReader->GetFilename() == filenameToRemove ) {
170 m_data.erase(dataIter);
176 inline int PositionMultiMerger::Size(void) const {
177 return m_data.size();
180 inline ReaderAlignment PositionMultiMerger::TakeFirst(void) {
181 DataIterator first = m_data.begin();
182 ReaderAlignment next = (*first).second;
187 // ------------------------------------------
188 // ReadNameMultiMerger implementation
190 inline void ReadNameMultiMerger::Add(ReaderAlignment value) {
191 BamAlignment* al = value.second;
192 if ( al->BuildCharData() ) {
193 const KeyType key(al->Name);
194 m_data.insert( ElementType(key, value) );
198 inline void ReadNameMultiMerger::Clear(void) {
202 inline const ReaderAlignment& ReadNameMultiMerger::First(void) const {
203 const ElementType& entry = (*m_data.begin());
207 inline bool ReadNameMultiMerger::IsEmpty(void) const {
208 return m_data.empty();
211 inline void ReadNameMultiMerger::Remove(BamReader* reader) {
213 if ( reader == 0 ) return;
214 const std::string filenameToRemove = reader->GetFilename();
216 // iterate over readers in cache
217 DataIterator dataIter = m_data.begin();
218 DataIterator dataEnd = m_data.end();
219 for ( ; dataIter != dataEnd; ++dataIter ) {
220 const ValueType& entry = (*dataIter).second;
221 const BamReader* entryReader = entry.first;
222 if ( entryReader == 0 ) continue;
224 // remove iterator on match
225 if ( entryReader->GetFilename() == filenameToRemove ) {
226 m_data.erase(dataIter);
233 inline int ReadNameMultiMerger::Size(void) const {
234 return m_data.size();
237 inline ReaderAlignment ReadNameMultiMerger::TakeFirst(void) {
238 DataIterator first = m_data.begin();
239 ReaderAlignment next = (*first).second;
244 // ------------------------------------------
245 // UnsortedMultiMerger implementation
247 inline void UnsortedMultiMerger::Add(ReaderAlignment value) {
248 m_data.push_back(value);
251 inline void UnsortedMultiMerger::Clear(void) {
252 for (size_t i = 0; i < m_data.size(); ++i )
256 inline const ReaderAlignment& UnsortedMultiMerger::First(void) const {
257 return m_data.front();
260 inline bool UnsortedMultiMerger::IsEmpty(void) const {
261 return m_data.empty();
264 inline void UnsortedMultiMerger::Remove(BamReader* reader) {
266 if ( reader == 0 ) return;
267 const std::string filenameToRemove = reader->GetFilename();
269 // iterate over readers in cache
270 DataIterator dataIter = m_data.begin();
271 DataIterator dataEnd = m_data.end();
272 for ( ; dataIter != dataEnd; ++dataIter ) {
273 const BamReader* entryReader = (*dataIter).first;
274 if ( entryReader == 0 ) continue;
276 // remove iterator on match
277 if ( entryReader->GetFilename() == filenameToRemove ) {
278 m_data.erase(dataIter);
284 inline int UnsortedMultiMerger::Size(void) const {
285 return m_data.size();
288 inline ReaderAlignment UnsortedMultiMerger::TakeFirst(void) {
289 ReaderAlignment first = m_data.front();
290 m_data.erase( m_data.begin() );
294 } // namespace Internal
295 } // namespace BamTools
297 #endif // BAMMULTIMERGER_P_H