content: /*
   * Copyright (C) 2015 The Android Open Source Project
   *
   * 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.
   */
  
  package androidx.constraintlayout.core;
  
  /**
   * Helper class for crating pools of objects. An example use looks like this:
   * <pre>
   * public class MyPooledClass {
   *
   *     private static final SimplePool<MyPooledClass> sPool =
   *             new SimplePool<MyPooledClass>(10);
   *
   *     public static MyPooledClass obtain() {
   *         MyPooledClass instance = sPool.acquire();
   *         return (instance != null) ? instance : new MyPooledClass();
   *     }
   *
   *     public void recycle() {
   *          // Clear state if needed.
   *          sPool.release(this);
   *     }
   *
   *     . . .
   * }
   * </pre>
   */
  final class Pools {
      private static final boolean DEBUG = false;
  
      /**
       * Interface for managing a pool of objects.
       *
       * @param <T> The pooled type.
       */
      interface Pool<T> {
  
          /**
           * @return An instance from the pool if such, null otherwise.
           */
          T acquire();
  
          /**
           * Release an instance to the pool.
           *
           * @param instance The instance to release.
           * @return Whether the instance was put in the pool.
           * @throws IllegalStateException If the instance is already in the pool.
           */
          boolean release(T instance);
  
          /**
           * Try releasing all instances at the same time
           *
           * @param variables the variables to release
           * @param count     the number of variables to release
           */
          void releaseAll(T[] variables, int count);
      }
  
      private Pools() {
          /* do nothing - hiding constructor */
      }
  
      /**
       * Simple (non-synchronized) pool of objects.
       *
       * @param <T> The pooled type.
       */
      static class SimplePool<T> implements Pool<T> {
          private final Object[] mPool;
  
          private int mPoolSize;
  
          /**
           * Creates a new instance.
           *
           * @param maxPoolSize The max pool size.
           * @throws IllegalArgumentException If the max pool size is less than zero.
           */
          SimplePool(int maxPoolSize) {
              if (maxPoolSize <= 0) {
                  throw new IllegalArgumentException("The max pool size must be > 0");
              }
              mPool = new Object[maxPoolSize];
          }
  
          @Override
          @SuppressWarnings("unchecked")
          public T acquire() {
              if (mPoolSize > 0) {
                  final int lastPooledIndex = mPoolSize - 1;
                  T instance = (T) mPool[lastPooledIndex];
                  mPool[lastPooledIndex] = null;
                  mPoolSize--;
                  return instance;
              }
              return null;
          }
  
          @Override
          public boolean release(T instance) {
              if (DEBUG) {
                  if (isInPool(instance)) {
                      throw new IllegalStateException("Already in the pool!");
                  }
              }
              if (mPoolSize < mPool.length) {
                  mPool[mPoolSize] = instance;
                  mPoolSize++;
                  return true;
              }
              return false;
          }
  
          @Override
          public void releaseAll(T[] variables, int count) {
              if (count > variables.length) {
                  count = variables.length;
              }
              for (int i = 0; i < count; i++) {
                  T instance = variables[i];
                  if (DEBUG) {
                      if (isInPool(instance)) {
                          throw new IllegalStateException("Already in the pool!");
                      }
                  }
                  if (mPoolSize < mPool.length) {
                      mPool[mPoolSize] = instance;
                      mPoolSize++;
                  }
              }
          }
  
          private boolean isInPool(T instance) {
              for (int i = 0; i < mPoolSize; i++) {
                  if (mPool[i] == instance) {
                      return true;
                  }
              }
              return false;
          }
      }
  
  }
  