From 259a1b517ecb8e43b4de07be02d5d51dee0e5e99 Mon Sep 17 00:00:00 2001
From: Scott Snyder <scott.snyder@cern.ch>
Date: Wed, 25 Jan 2017 02:02:33 +0100
Subject: [PATCH] Implement insertMove. (xAODTrigger-00-00-56)

	* Tagging xAODTrigger-00-00-56.
	* xAODTrigger/versions/ByteStreamAuxContainer_v1.h,
	Root/ByteStreamAuxContainer_v1.cxx: Implement insertMove.
	* test/ut_xaodtrigger_bytestreamauxcontainer_v1_test.cxx,
	share/ut_xaodtrigger_bytestreamauxcontainer_v1_test.ref: Test it.
---
 Event/xAOD/xAODTrigger/CMakeLists.txt         |   6 +-
 .../Root/ByteStreamAuxContainer_v1.cxx        |  77 +++++++++-
 ...trigger_bytestreamauxcontainer_v1_test.ref |   1 +
 ...trigger_bytestreamauxcontainer_v1_test.cxx | 134 ++++++++++++++++++
 .../versions/ByteStreamAuxContainer_v1.h      |  17 ++-
 5 files changed, 226 insertions(+), 9 deletions(-)
 create mode 100644 Event/xAOD/xAODTrigger/share/ut_xaodtrigger_bytestreamauxcontainer_v1_test.ref
 create mode 100644 Event/xAOD/xAODTrigger/test/ut_xaodtrigger_bytestreamauxcontainer_v1_test.cxx

diff --git a/Event/xAOD/xAODTrigger/CMakeLists.txt b/Event/xAOD/xAODTrigger/CMakeLists.txt
index 7f6bd363de0..30814b2a6a7 100644
--- a/Event/xAOD/xAODTrigger/CMakeLists.txt
+++ b/Event/xAOD/xAODTrigger/CMakeLists.txt
@@ -1,4 +1,4 @@
-# $Id: CMakeLists.txt 744561 2016-05-03 16:08:19Z krasznaa $
+# $Id: CMakeLists.txt 793760 2017-01-25 02:02:33Z ssnyder $
 ################################################################################
 # Package: xAODTrigger
 ################################################################################
@@ -33,3 +33,7 @@ atlas_add_dictionary( xAODTriggerDict
    xAODTrigger/selection.xml
    LINK_LIBRARIES xAODTrigger
    EXTRA_FILES Root/dict/*.cxx )
+
+atlas_add_test( ut_xaodtrigger_bytestreamauxcontainer_v1_test
+  SOURCES test/ut_xaodtrigger_bytestreamauxcontainer_v1_test.cxx
+  LINK_LIBRARIES AthContainers xAODTrigger )
diff --git a/Event/xAOD/xAODTrigger/Root/ByteStreamAuxContainer_v1.cxx b/Event/xAOD/xAODTrigger/Root/ByteStreamAuxContainer_v1.cxx
index 139f8879ed8..f348915f8f6 100644
--- a/Event/xAOD/xAODTrigger/Root/ByteStreamAuxContainer_v1.cxx
+++ b/Event/xAOD/xAODTrigger/Root/ByteStreamAuxContainer_v1.cxx
@@ -2,7 +2,7 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id: ByteStreamAuxContainer_v1.cxx 793282 2017-01-20 20:00:48Z ssnyder $
+// $Id: ByteStreamAuxContainer_v1.cxx 793760 2017-01-25 02:02:33Z ssnyder $
 
 // System include(s):
 #include <iostream>
@@ -199,9 +199,8 @@ namespace xAOD {
    }
 
 
-   size_t ByteStreamAuxContainer_v1::size() const
+   size_t ByteStreamAuxContainer_v1::size_noLock() const
    {
-     guard_t guard (m_mutex);
      auxid_set_t::const_iterator i = m_auxids.begin();
      auxid_set_t::const_iterator end = m_auxids.end();
      for (; i != end; ++i) {
@@ -220,6 +219,13 @@ namespace xAOD {
      return 0;
    }
 
+   size_t ByteStreamAuxContainer_v1::size() const
+   {
+     guard_t guard (m_mutex);
+     return size_noLock();
+   }
+
+
    void* ByteStreamAuxContainer_v1::getData( auxid_t auxid, size_t size,
                                              size_t capacity ) {
 
@@ -328,6 +334,71 @@ namespace xAOD {
       return;
    }
 
+   bool ByteStreamAuxContainer_v1::insertMove( size_t pos,
+                                               IAuxStore& other,
+                                               const SG::auxid_set_t& ignore_in) {
+
+      guard_t guard( m_mutex );
+
+      // This operation is not allowed on a locked container:
+      if( m_locked ) {
+         throw SG::ExcStoreLocked( "insertMove" );
+      }
+
+      const SG::AuxTypeRegistry& r = SG::AuxTypeRegistry::instance();
+      bool nomove = true;
+      size_t other_size = other.size();
+
+      SG::auxid_set_t ignore = ignore_in;
+
+      // Do the operation on the static variables:
+      for (SG::auxid_t id : m_auxids) {
+        SG::IAuxTypeVector* v_dst = nullptr;
+        if (id < m_dynamicVecs.size())
+          v_dst = m_dynamicVecs[id];
+        if (!v_dst && id < m_staticVecs.size())
+          v_dst = m_staticVecs[id];
+        if (v_dst) {
+          ignore.insert (id);
+          if (other.getData (id)) {
+            void* src_ptr = other.getData (id, other_size, other_size);
+            if (src_ptr) {
+              if (!v_dst->insertMove (pos, src_ptr,
+                                      reinterpret_cast<char*>(src_ptr) + other_size*r.getEltSize(id)))
+                nomove = false;
+            }
+          }
+          else {
+            const void* orig = v_dst->toPtr();
+            v_dst->shift (pos, other_size);
+            if (orig != v_dst->toPtr())
+              nomove = false;
+          }
+        }
+      }
+
+      // Add any new variables not present in the original container.
+      for (SG::auxid_t id : other.getAuxIDs()) {
+        if (m_auxids.find(id) == m_auxids.end() &&
+            ignore.find(id) == ignore.end())
+        {
+          if (other.getData (id)) {
+            void* src_ptr = other.getData (id, other_size, other_size);
+            if (src_ptr) {
+              size_t sz = size_noLock();
+              getData1 (id, sz, sz, true, false);
+              m_dynamicVecs[id]->resize (sz - other_size);
+              m_dynamicVecs[id]->insertMove (pos, src_ptr, reinterpret_cast<char*>(src_ptr) + other_size*r.getEltSize(id));
+              nomove = false;
+            }
+          }
+        }
+      }
+
+      return nomove;
+   }
+
+
    void ByteStreamAuxContainer_v1::reset() {
 
       guard_t guard (m_mutex);
diff --git a/Event/xAOD/xAODTrigger/share/ut_xaodtrigger_bytestreamauxcontainer_v1_test.ref b/Event/xAOD/xAODTrigger/share/ut_xaodtrigger_bytestreamauxcontainer_v1_test.ref
new file mode 100644
index 00000000000..a5bce3fd256
--- /dev/null
+++ b/Event/xAOD/xAODTrigger/share/ut_xaodtrigger_bytestreamauxcontainer_v1_test.ref
@@ -0,0 +1 @@
+test1
diff --git a/Event/xAOD/xAODTrigger/test/ut_xaodtrigger_bytestreamauxcontainer_v1_test.cxx b/Event/xAOD/xAODTrigger/test/ut_xaodtrigger_bytestreamauxcontainer_v1_test.cxx
new file mode 100644
index 00000000000..1fa8c1e4650
--- /dev/null
+++ b/Event/xAOD/xAODTrigger/test/ut_xaodtrigger_bytestreamauxcontainer_v1_test.cxx
@@ -0,0 +1,134 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file xAODRootAccess/test/ut_xaodtrigger_bytestreamauxcontainer_v1_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2017
+ * @brief Unit tests for ByteStreamAuxContainer_v1 (sadly incomplete).
+ */
+
+
+#undef NDEBUG
+#include "xAODTrigger/versions/ByteStreamAuxContainer_v1.h"
+#include "AthContainers/AuxTypeRegistry.h"
+#include "AthContainers/AuxStoreInternal.h"
+#include <iostream>
+#include <sstream>
+#include <cassert>
+
+
+class AuxContainerTest
+  : public xAOD::ByteStreamAuxContainer_v1
+{
+public:
+  AuxContainerTest();
+
+  std::vector<int> anInt;
+};
+
+
+AuxContainerTest::AuxContainerTest()
+{
+  AUX_VARIABLE(anInt);
+}
+
+
+void test1()
+{
+  std::cout << "test1\n";
+
+  SG::auxid_t ityp1 = SG::AuxTypeRegistry::instance().getAuxID<int> ("anInt");
+  SG::auxid_t ityp2 = SG::AuxTypeRegistry::instance().getAuxID<int> ("anotherInt");
+  SG::auxid_t ityp3 = SG::AuxTypeRegistry::instance().getAuxID<int> ("anInt3");
+  SG::auxid_t ityp4 = SG::AuxTypeRegistry::instance().getAuxID<int> ("anInt4");
+
+  AuxContainerTest s1;
+  s1.resize(5);
+  s1.reserve(20);
+
+  int* i1 = reinterpret_cast<int*> (s1.getData(ityp1, 5, 20));
+  int* i2 = reinterpret_cast<int*> (s1.getData(ityp2, 5, 20));
+
+  for (int i=0; i<5; i++) {
+    i1[i] = i;
+    i2[i] = i+100;
+  }
+
+  SG::AuxStoreInternal s2;
+  s2.resize(5);
+
+  int* i1_2 = reinterpret_cast<int*> (s2.getData(ityp1, 5, 5));
+  int* i3_2 = reinterpret_cast<int*> (s2.getData(ityp3, 5, 5));
+  int* i4_2 = reinterpret_cast<int*> (s2.getData(ityp4, 5, 5));
+  for (int i=0; i<5; i++) {
+    i1_2[i] = i+10;
+    i3_2[i] = i+110;
+    i4_2[i] = i+210;
+  }
+
+  SG::auxid_set_t ignore { ityp4 };
+
+  s1.insertMove (3, s2, ignore);
+  assert (s1.size() == 10);
+  s1.reserve(20);
+  assert (s1.getData(ityp4) == nullptr);
+  const int* i3 = reinterpret_cast<const int*> (s1.getData(ityp3));
+  assert (i3 != 0);
+  i1 = reinterpret_cast<int*> (s1.getData(ityp1, 10, 20));
+  i2 = reinterpret_cast<int*> (s1.getData(ityp2, 10, 20));
+  for (int i=0; i<3; i++) {
+    assert (i1[i] == i);
+    assert (i2[i] == i+100);
+    assert (i3[i] == 0);
+  }
+  for (int i=0; i<5; i++) {
+    assert (i1[3+i] == i+10);
+    assert (i2[3+i] == 0);
+    assert (i3[3+i] == i+110);
+  }
+  for (int i=3; i<5; i++) {
+    assert (i1[5+i] == i);
+    assert (i2[5+i] == i+100);
+    assert (i3[5+i] == 0);
+  }
+
+  for (int i=0; i<5; i++) {
+    i1_2[i] = i+20;
+    i3_2[i] = i+120;
+  }
+  s1.insertMove (10, s2, ignore);
+  assert (s1.size() == 15);
+  i1 = reinterpret_cast<int*> (s1.getData(ityp1, 15, 20));
+  i2 = reinterpret_cast<int*> (s1.getData(ityp2, 15, 20));
+  i3 = reinterpret_cast<int*> (s1.getData(ityp3, 15, 20));
+  for (int i=0; i<3; i++) {
+    assert (i1[i] == i);
+    assert (i2[i] == i+100);
+    assert (i3[i] == 0);
+  }
+  for (int i=0; i<5; i++) {
+    assert (i1[3+i] == i+10);
+    assert (i2[3+i] == 0);
+    assert (i3[3+i] == i+110);
+  }
+  for (int i=3; i<5; i++) {
+    assert (i1[5+i] == i);
+    assert (i2[5+i] == i+100);
+    assert (i3[5+i] == 0);
+  }
+  for (int i=0; i<5; i++) {
+    assert (i1[10+i] == i+20);
+    assert (i2[10+i] == 0);
+    assert (i3[10+i] == i+120);
+  }
+}
+
+
+int main()
+{
+  test1();
+  return 0;
+}
diff --git a/Event/xAOD/xAODTrigger/xAODTrigger/versions/ByteStreamAuxContainer_v1.h b/Event/xAOD/xAODTrigger/xAODTrigger/versions/ByteStreamAuxContainer_v1.h
index 70e35887ca5..601cb8362f0 100644
--- a/Event/xAOD/xAODTrigger/xAODTrigger/versions/ByteStreamAuxContainer_v1.h
+++ b/Event/xAOD/xAODTrigger/xAODTrigger/versions/ByteStreamAuxContainer_v1.h
@@ -4,7 +4,7 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id: ByteStreamAuxContainer_v1.h 793282 2017-01-20 20:00:48Z ssnyder $
+// $Id: ByteStreamAuxContainer_v1.h 793760 2017-01-25 02:02:33Z ssnyder $
 #ifndef XAODTRIGGER_VERSIONS_BYTESTREAMAUXCONTAINER_V1_H
 #define XAODTRIGGER_VERSIONS_BYTESTREAMAUXCONTAINER_V1_H
 
@@ -38,8 +38,8 @@ namespace xAOD {
    ///
    /// @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
    ///
-   /// $Revision: 793282 $
-   /// $Date: 2017-01-20 21:00:48 +0100 (Fri, 20 Jan 2017) $
+   /// $Revision: 793760 $
+   /// $Date: 2017-01-25 03:02:33 +0100 (Wed, 25 Jan 2017) $
    ///
    class ByteStreamAuxContainer_v1
      : public SG::IAuxStore
@@ -104,7 +104,11 @@ namespace xAOD {
       virtual void reserve( size_t size );
       /// Shift the contents of the stored arrays
       virtual void shift( size_t pos, ptrdiff_t offs );
-
+      /// Insert contents of another store via move.
+      virtual bool insertMove (size_t pos,
+                               IAuxStore& other,
+                               const SG::auxid_set_t& ignore);
+ 
       /// @}
 
       /// Function resetting the internal (cached) state of the object
@@ -127,7 +131,10 @@ namespace xAOD {
                       std::vector< T >& vec );
 
    private:
-      /// Function retrieving a simple dynamic variable.
+      /// Internal method: return size without taking out the lock.
+      size_t size_noLock() const;
+
+     /// Function retrieving a simple dynamic variable.
       /// If capacity > 0, a new verable will be created if necessary.
       template< typename T >
       void* getData1( auxid_t auxid,
-- 
GitLab