diff --git a/Event/EventContainers/CMakeLists.txt b/Event/EventContainers/CMakeLists.txt
index c65a935b9a0890f2d58a3d8f3a7ef5bca1786840..a78bf3a7d82bbadd6dda1d024159c9ea2ce25e62 100644
--- a/Event/EventContainers/CMakeLists.txt
+++ b/Event/EventContainers/CMakeLists.txt
@@ -34,3 +34,8 @@ atlas_add_test( IDStressTest SOURCES test/IDC_Realistic_Test.cxx
                 LINK_LIBRARIES Identifier AthenaKernel GaudiKernel EventContainers
                 EXTRA_PATTERNS "elapsed|^no lock time|^deleted|^countHit|^lock time"
               )
+atlas_add_test( IDCValueTest SOURCES test/IDCValueTest.cxx
+                INCLUDE_DIRS src test EventContainers
+                LINK_LIBRARIES Identifier AthenaKernel GaudiKernel EventContainers
+                EXTRA_PATTERNS ""
+              )
\ No newline at end of file
diff --git a/Event/EventContainers/EventContainers/IdentifiableCache.h b/Event/EventContainers/EventContainers/IdentifiableCache.h
index e1c805941efc95b0c66c32bbbb1c7dfd51d21db5..0c0d3aa7d2216f8552fead3e92a82c81b1504e79 100644
--- a/Event/EventContainers/EventContainers/IdentifiableCache.h
+++ b/Event/EventContainers/EventContainers/IdentifiableCache.h
@@ -1,7 +1,7 @@
 // This file's extension implies that it's C, but it's really -*- C++ -*-.
 
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 // $Id: IdentifiableCache.h 791541 2017-01-09 10:43:53Z smh $
@@ -45,8 +45,8 @@ public:
   {
   }
 
-  IdentifiableCache (IdentifierHash maxHash, const Maker* maker, size_t /*lockBucketSize*/)
-    : IdentifiableCacheBase (maxHash, maker)
+  IdentifiableCache (IdentifierHash maxHash, const Maker* maker, size_t lockBucketSize)
+    : IdentifiableCacheBase (maxHash, maker, lockBucketSize)
   {
   }
 
diff --git a/Event/EventContainers/EventContainers/IdentifiableContainerMT.h b/Event/EventContainers/EventContainers/IdentifiableContainerMT.h
index ad26ea3c0071385472fd16d93d4d44bf1cfc333d..1fd416dd8eb4182729c2c562d9a09c7f51c4834c 100644
--- a/Event/EventContainers/EventContainers/IdentifiableContainerMT.h
+++ b/Event/EventContainers/EventContainers/IdentifiableContainerMT.h
@@ -252,7 +252,7 @@ public:
     virtual StatusCode addOrDelete(std::unique_ptr<T>, IdentifierHash hashId) override final;
 
     ///identical to previous excepts allows counting of deletions
-    virtual StatusCode addOrDelete(std::unique_ptr<T>, IdentifierHash hashId, bool &deleted);
+    StatusCode addOrDelete(std::unique_ptr<T>, IdentifierHash hashId, bool &deleted);
 
     ///Like the other add methods but optimized for changing from the inprogress state
     StatusCode addLock(std::unique_ptr<T> ptr, IdentifierHash hashId);
diff --git a/Event/EventContainers/EventContainers/IdentifiableValueCache.h b/Event/EventContainers/EventContainers/IdentifiableValueCache.h
new file mode 100644
index 0000000000000000000000000000000000000000..c764683e0ee7fd03a53a2b5a1bb0e68ae01be96c
--- /dev/null
+++ b/Event/EventContainers/EventContainers/IdentifiableValueCache.h
@@ -0,0 +1,56 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef EVENTCONTAINERS_IDENTIFIABLEVALUECACHE_H
+#define EVENTCONTAINERS_IDENTIFIABLEVALUECACHE_H
+
+#include <atomic>
+#include <vector>
+
+
+
+template<class T, T EMPTYVALUE>
+class IdentifiableValueCache{
+
+public:
+  static constexpr T emptyValue() {
+      return EMPTYVALUE;
+   }
+
+   IdentifiableValueCache(const IdentifiableValueCache&) = delete;
+   IdentifiableValueCache(size_t maxSize)
+      : m_vec(maxSize)
+   {
+        for(auto &x : m_vec) x.store(emptyValue(), std::memory_order_relaxed);
+   }
+
+   void forceReset(){
+        for(auto &x : m_vec) x.store(emptyValue(), std::memory_order_relaxed);
+   }
+
+   size_t maxSize() const { return m_vec.size(); }
+
+   ~IdentifiableValueCache() = default;
+
+   T retrieve(size_t i){
+        return m_vec.at(i).load();
+   }
+
+   bool present(size_t i){
+        return m_vec.at(i).load() != emptyValue();
+   }
+
+   bool setOrDrop(size_t i, const T &value){
+       T val = emptyValue();
+       return m_vec.at(i).compare_exchange_strong(val, value);
+   }
+
+   const std::vector<std::atomic<T>>& rawReadAccess() const { return m_vec; }
+
+private:
+   std::vector<std::atomic<T>> m_vec;
+
+};
+
+#endif
diff --git a/Event/EventContainers/EventContainers/IdentifiableValueContainer.h b/Event/EventContainers/EventContainers/IdentifiableValueContainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..4d8b1a000c552e669c77520b424146e0b63eda4f
--- /dev/null
+++ b/Event/EventContainers/EventContainers/IdentifiableValueContainer.h
@@ -0,0 +1,79 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef EVENTCONTAINERS_IDENTIFIABLECVALUEONTAINER_H
+#define EVENTCONTAINERS_IDENTIFIABLEVALUECONTAINER_H
+
+#include "EventContainers/IdentifiableValueCache.h"
+
+template<class T, T EMPTYVALUE>
+class IdentifiableValueContainer{
+
+public:
+
+   static constexpr T emptyValue() {
+      return EMPTYVALUE;
+   }
+
+   IdentifiableValueContainer(const IdentifiableValueContainer<T,EMPTYVALUE>&) = delete;
+
+   ~IdentifiableValueContainer()  { if(m_own) delete m_cache; }
+   IdentifiableValueContainer(size_t maxSize) : m_mask(maxSize, false), m_own(true)
+   {
+       m_cache = new IdentifiableValueCache<T, EMPTYVALUE>(maxSize);
+   }
+
+   IdentifiableValueContainer(IdentifiableValueCache<T,EMPTYVALUE> *ptr) : m_mask(ptr->maxSize()),
+   m_cache(ptr), m_own(false)
+   {}
+
+   bool present(size_t i) const
+   {
+       return m_mask.at(i);
+   }
+
+   bool setOrDrop(size_t i, const T &value){
+      bool b = m_cache->setOrDrop(i, value);
+      m_mask[i] = true;
+      return b;
+   }
+
+   size_t maxSize() const { return m_mask.size(); }
+
+   size_t numberSet() const{
+        size_t count = 0;
+        for(bool b : m_mask) count += b;
+        return count;
+   }
+
+   bool tryAddFromCache(size_t i){
+      if(i >= m_mask.size()) return false;
+      bool b = m_cache->present(i);
+      m_mask[i] = b;
+      return b;
+   }
+
+   T retrieve(size_t i) const{
+        if(m_mask[i]) return m_cache->retrieve(i);
+        else return emptyValue();
+   }
+
+   std::vector<std::pair<size_t, T>> getAll() const{
+      std::vector<std::pair<size_t, T>> list;
+      const auto& raw = m_cache->rawReadAccess();
+      for(size_t i =0; i<m_mask.size(); i++){
+          if(m_mask[i]) list.emplace_back(i, raw[i].load());
+      }
+      return list;
+   }
+
+   const std::vector<std::atomic<T>>& wholeEventReadAccess() const { return m_cache->rawReadAccess(); }
+
+private:
+   std::vector<bool> m_mask;
+   IdentifiableValueCache<T, EMPTYVALUE> *m_cache;
+   bool m_own;
+};
+
+#endif
\ No newline at end of file
diff --git a/Event/EventContainers/share/IDCValueTest.ref b/Event/EventContainers/share/IDCValueTest.ref
new file mode 100644
index 0000000000000000000000000000000000000000..1a2c5e2c1a5a6ea943180b9523fa1816f9169236
--- /dev/null
+++ b/Event/EventContainers/share/IDCValueTest.ref
@@ -0,0 +1,2 @@
+Threw exception correctly
+Completed - no errors
diff --git a/Event/EventContainers/test/IDCValueTest.cxx b/Event/EventContainers/test/IDCValueTest.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..0c223f35b28d937333138e908b053327fa860da5
--- /dev/null
+++ b/Event/EventContainers/test/IDCValueTest.cxx
@@ -0,0 +1,46 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+#include "EventContainers/IdentifiableValueContainer.h"
+
+#include <cstdlib>
+#include <iostream>
+#include <limits>
+
+typedef IdentifiableValueCache<int, std::numeric_limits<int>::min()> int100cache;
+typedef IdentifiableValueContainer<int, std::numeric_limits<int>::min()> int100container;
+
+int main(){
+   auto *cache = new int100cache(100);
+   auto *container = new int100container(cache);
+   auto *container2 = new int100container(cache);
+   static_assert(cache->emptyValue() == std::numeric_limits<int>::min());
+   if(container->maxSize()!= 100) std::abort();
+   if(!container->setOrDrop(50, 29)) std::abort();
+   if(!container->setOrDrop(51, -29)) std::abort();
+   if(!container->setOrDrop(52, -9)) std::abort();
+   if(container->setOrDrop(52, 10) == true) std::abort(); //check if repeated setting passes
+   if(container->retrieve(52) != -9) std::abort();
+
+   if(container->present(50)==false || container->present(51)==false || container->present(52)==false) std::abort();
+   if(container2->tryAddFromCache(50) == false) std::abort();
+   if(container2->getAll().size()!= 1) std::abort();
+   if(container->getAll().size()!= 3) std::abort();
+   if(container2->retrieve(50) != 29) std::abort();
+   if(container2->present(51) == true) std::abort();
+   if(container2->retrieve(51) != container2->emptyValue()) std::abort();
+   bool except =false;
+   try{
+         container->setOrDrop(150, -29);
+   }catch(const std::out_of_range& ex)
+   {
+      except = true;
+      std::cout << "Threw exception correctly" << std::endl;
+   }
+   if(except == false) std::abort();
+   delete container2;
+   delete container;
+   delete cache;
+   std::cout << "Completed - no errors" << std::endl;
+   return 0;
+}
\ No newline at end of file