All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.orientechnologies.common.concur.resource.OReentrantResourcePool Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2010-2012 Luca Garulli (l.garulli--at--orientechnologies.com)
 *
 * 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 com.orientechnologies.common.concur.resource;

import com.orientechnologies.common.concur.lock.OLockException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Reentrant implementation of Resource Pool. It manages multiple resource acquisition on thread local map. If you're looking for a
 * Reentrant implementation look at #OReentrantResourcePool.
 * 
 * @author Andrey Lomakin (a.lomakin--at--orientechnologies.com)
 * @author Luca Garulli (l.garulli--at--orientechnologies.com)
 * @see OResourcePool
 */
public class OReentrantResourcePool extends OResourcePool {
  private final ThreadLocal>> activeResources = new ThreadLocal>>();

  private static final class ResourceHolder {
    private final V resource;
    private int     counter = 1;

    private ResourceHolder(V resource) {
      this.resource = resource;
    }
  }

  public OReentrantResourcePool(final int maxResources, final OResourcePoolListener listener) {
    super(maxResources, listener);
  }

  public V getResource(K key, final long maxWaitMillis, Object... additionalArgs) throws OLockException {
    Map> resourceHolderMap = activeResources.get();

    if (resourceHolderMap == null) {
      resourceHolderMap = new HashMap>();
      activeResources.set(resourceHolderMap);
    }

    final ResourceHolder holder = resourceHolderMap.get(key);
    if (holder != null) {
      holder.counter++;
      return holder.resource;
    }
    try {
      final V res = super.getResource(key, maxWaitMillis, additionalArgs);
      resourceHolderMap.put(key, new ResourceHolder(res));
      return res;

    } catch (RuntimeException e) {
      resourceHolderMap.remove(key);

      // PROPAGATE IT
      throw e;
    }
  }

  public boolean returnResource(final V res) {
    final Map> resourceHolderMap = activeResources.get();
    if (resourceHolderMap != null) {
      K keyToRemove = null;
      for (Map.Entry> entry : resourceHolderMap.entrySet()) {
        final ResourceHolder holder = entry.getValue();
        if (holder.resource.equals(res)) {
          holder.counter--;
          assert holder.counter >= 0;
          if (holder.counter > 0)
            return false;

          keyToRemove = entry.getKey();
          break;
        }
      }

      resourceHolderMap.remove(keyToRemove);
    }

    return super.returnResource(res);
  }

  public int getConnectionsInCurrentThread(final K key) {
    final Map> resourceHolderMap = activeResources.get();
    if (resourceHolderMap == null)
      return 0;

    final ResourceHolder holder = resourceHolderMap.get(key);
    if (holder == null)
      return 0;

    return holder.counter;
  }

  public void remove(final V res) {
    this.resources.remove(res);

    final List activeResourcesToRemove = new ArrayList();
    final Map> activeResourcesMap = activeResources.get();

    if (activeResourcesMap != null) {
      for (Map.Entry> entry : activeResourcesMap.entrySet()) {
        final ResourceHolder holder = entry.getValue();
        if (holder.resource.equals(res))
          activeResourcesToRemove.add(entry.getKey());
      }

      for (K resourceKey : activeResourcesToRemove) {
        activeResourcesMap.remove(resourceKey);
        sem.release();
      }
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy