/* 
 * Licensed under the Apache License, Version 2.0 (the "License");
 *
 * You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Contributions from 2013-2017 where performed either by US government 
 * employees, or under US Veterans Health Administration contracts. 
 *
 * US Veterans Health Administration contributions by government employees
 * are work of the U.S. Government and are not subject to copyright
 * protection in the United States. Portions contributed by government 
 * employees are USGovWork (17USC §105). Not subject to copyright. 
 * 
 * Contribution by contractors to the US Veterans Health Administration
 * during this period are contractually contributed under the
 * Apache License, Version 2.0.
 *
 * See: https://www.usa.gov/government-works
 * 
 * Contributions prior to 2013:
 *
 * Copyright (C) International Health Terminology Standards Development Organisation.
 * Licensed under the Apache License, Version 2.0.
 *
 */



package sh.isaac.api.memory;

//~--- JDK imports ------------------------------------------------------------

import java.util.Set;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

//~--- classes ----------------------------------------------------------------

/**
 * Created by kec on 4/10/15.
 */
public class HoldInMemoryCache {
   /** The Constant CACHE_SIZE. */
   private static final int CACHE_SIZE = 512;

   /** The Constant GENERATIONS. */
   private static final int GENERATIONS = 3;

   /** The Constant queue. */
   private static final LinkedBlockingDeque<Set<MemoryManagedReference>> queue = new LinkedBlockingDeque();

   /** The Constant cacheRef. */
   private static final AtomicReference<Set<MemoryManagedReference>> cacheRef =
      new AtomicReference<>(new ConcurrentSkipListSet<>());

   /** The Constant cacheCount. */
   private static final AtomicInteger cacheCount = new AtomicInteger();

   //~--- methods -------------------------------------------------------------

   /**
    * Adds the to cache.
    *
    * @param newRef the new ref
    */
   public static void addToCache(MemoryManagedReference newRef) {
      final Set<MemoryManagedReference> cache = cacheRef.get();

      if (!cache.contains(newRef)) {
         newRef.cacheEntry();
         cache.add(newRef);

         final int count = cacheCount.incrementAndGet();

         if (count > CACHE_SIZE) {
            if (cacheRef.compareAndSet(cache, new ConcurrentSkipListSet<>())) {
               queue.addFirst(cache);

               while (queue.size() > GENERATIONS) {
                  final Set<MemoryManagedReference> oldCache = queue.removeLast();

                  oldCache.stream().forEach(memoryManagedReference -> {
                                      memoryManagedReference.cacheExit();
                                   });
               }
            }
         }
      }
   }

   /**
    * Clear cache.
    */
   public static void clearCache() {
      queue.stream().forEach((Set<MemoryManagedReference> referenceSet) -> {
                       referenceSet.stream().forEach((MemoryManagedReference ref) -> {
                                               ref.cacheExit();
                                               referenceSet.remove(ref);
                                            });
                    });
   }
}


@@ -3192,22 +3192,20 @@
 eue.
-remove
+poll
 Last();%0A
 %0A   
@@ -3196,25 +3196,69 @@
 pollLast();%0A
-%0A
+                  if (oldCache != null) %7B%0A   
             
@@ -3355,16 +3355,19 @@
         
+   
 memoryMa
@@ -3421,35 +3421,58 @@
                 
-%7D);
+   %7D);%0A                  %7D
 %0A               

fix a threading bug