]> git.donarmstrong.com Git - bamtools.git/blobdiff - src/api/SamReadGroupDictionary.cpp
Minor version bump - 2.3.0
[bamtools.git] / src / api / SamReadGroupDictionary.cpp
index 7b8fad079cdac618eda4880c54c60857bde50472..007221a7cd030e0fd2a1d68e8086340d95a7e8e0 100644 (file)
@@ -2,7 +2,7 @@
 // SamReadGroupDictionary.cpp (c) 2010 Derek Barnett
 // Marth Lab, Department of Biology, Boston College
 // ---------------------------------------------------------------------------
-// Last modified: 12 October 2011 (DB)
+// Last modified: 16 October 2011 (DB)
 // ---------------------------------------------------------------------------
 // Provides methods for operating on a collection of SamReadGroup entries.
 // ***************************************************************************
@@ -19,32 +19,6 @@ using namespace std;
     Provides methods for operating on a collection of SamReadGroup entries.
 */
 
-/*! \typedef BamTools::SamReadGroupIterator
-    \brief mutable iterator for SamReadGroupDictionary data
-
-    \note This iterator, dereferenced, actually points to a
-    std::pair<std::string, SamReadGroup>, NOT a "plain old" SamReadGroup.
-    To retrieve the read group object:
-
-    \code
-        SamReadGroupIterator iter;
-        SamReadGroup& rg = (*iter).second // OR iter->second;
-    \endcode
-*/
-
-/*! \typedef BamTools::SamReadGroupConstIterator
-    \brief const iterator for SamReadGroupDictionary data
-
-    \note This iterator, dereferenced, actually points to a
-    std::pair<std::string, SamReadGroup>, NOT a "plain old" SamReadGroup.
-    To retrieve the read group object:
-
-    \code
-        SamReadGroupConstIterator iter;
-        const SamReadGroup& sq = (*iter).second // OR iter->second;
-    \endcode
-*/
-
 /*! \fn SamReadGroupDictionary::SamReadGroupDictionary(void)
     \brief constructor
 */
@@ -55,6 +29,7 @@ SamReadGroupDictionary::SamReadGroupDictionary(void) { }
 */
 SamReadGroupDictionary::SamReadGroupDictionary(const SamReadGroupDictionary& other)
     : m_data(other.m_data)
+    , m_lookupData(other.m_lookupData)
 { }
 
 /*! \fn SamReadGroupDictionary::~SamReadGroupDictionary(void)
@@ -70,8 +45,10 @@ SamReadGroupDictionary::~SamReadGroupDictionary(void) { }
     \param[in] readGroup entry to be added
 */
 void SamReadGroupDictionary::Add(const SamReadGroup& readGroup) {
-    if ( IsEmpty() || !Contains(readGroup) )
-        m_data[readGroup.ID] = readGroup;
+    if ( IsEmpty() || !Contains(readGroup) ) {
+        m_data.push_back(readGroup);
+        m_lookupData[readGroup.ID] = m_data.size() - 1;
+    }
 }
 
 /*! \fn void SamReadGroupDictionary::Add(const std::string& readGroupId)
@@ -98,7 +75,7 @@ void SamReadGroupDictionary::Add(const SamReadGroupDictionary& readGroups) {
     SamReadGroupConstIterator rgIter = readGroups.ConstBegin();
     SamReadGroupConstIterator rgEnd  = readGroups.ConstEnd();
     for ( ; rgIter != rgEnd; ++rgIter )
-        Add(rgIter->second);
+        Add(*rgIter);
 }
 
 /*! \fn void SamReadGroupDictionary::Add(const std::vector<SamReadGroup>& readGroups)
@@ -155,6 +132,7 @@ SamReadGroupConstIterator SamReadGroupDictionary::Begin(void) const {
 */
 void SamReadGroupDictionary::Clear(void) {
     m_data.clear();
+    m_lookupData.clear();
 }
 
 /*! \fn SamReadGroupConstIterator SamReadGroupDictionary::ConstBegin(void) const
@@ -180,7 +158,7 @@ SamReadGroupConstIterator SamReadGroupDictionary::ConstEnd(void) const {
     \return \c true if dictionary contains a read group with this ID
 */
 bool SamReadGroupDictionary::Contains(const std::string& readGroupId) const {
-    return ( m_data.find(readGroupId) != m_data.end() );
+    return ( m_lookupData.find(readGroupId) != m_lookupData.end() );
 }
 
 /*! \fn bool SamReadGroupDictionary::Contains(const SamReadGroup& readGroup) const
@@ -240,7 +218,22 @@ void SamReadGroupDictionary::Remove(const SamReadGroup& readGroup) {
     \sa Remove()
 */
 void SamReadGroupDictionary::Remove(const std::string& readGroupId) {
-    m_data.erase(readGroupId);
+
+    // skip if empty dictionary or if ID unknown
+    if ( IsEmpty() || !Contains(readGroupId) )
+        return;
+
+    // update 'lookup index' for every entry after @readGroupId
+    const size_t indexToRemove = m_lookupData[readGroupId];
+    const size_t numEntries = m_data.size();
+    for ( size_t i = indexToRemove+1; i < numEntries; ++i ) {
+        const SamReadGroup& rg = m_data.at(i);
+        --m_lookupData[rg.ID];
+    }
+
+    // erase entry from containers
+    m_data.erase( Begin() + indexToRemove );
+    m_lookupData.erase(readGroupId);
 }
 
 /*! \fn void SamReadGroupDictionary::Remove(const std::vector<SamReadGroup>& readGroups)
@@ -292,7 +285,13 @@ int SamReadGroupDictionary::Size(void) const {
     \return a modifiable reference to the SamReadGroup associated with the ID
 */
 SamReadGroup& SamReadGroupDictionary::operator[](const std::string& readGroupId) {
-    if ( !Contains(readGroupId) )
-        m_data[readGroupId] = SamReadGroup(readGroupId);
-    return m_data[readGroupId];
+
+    if ( !Contains(readGroupId) ) {
+        SamReadGroup rg(readGroupId);
+        m_data.push_back(rg);
+        m_lookupData[readGroupId] = m_data.size() - 1;
+    }
+
+    const size_t index = m_lookupData[readGroupId];
+    return m_data.at(index);
 }