Striped.java 7.43 KB
package com.google.common.util.concurrent;

import com.google.common.annotations.Beta;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.MapMaker;
import com.google.common.math.IntMath;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;

@Beta
public abstract class Striped<L>
{
  private static final Supplier<ReadWriteLock> a = new Supplier() {};
  
  private static <L> Striped<L> a(int paramInt, Supplier<L> paramSupplier)
  {
    if (paramInt < 1024) {
      return new f(paramInt, paramSupplier);
    }
    return new b(paramInt, paramSupplier);
  }
  
  public static Striped<Lock> lazyWeakLock(int paramInt)
  {
    a(paramInt, new Supplier() {});
  }
  
  public static Striped<ReadWriteLock> lazyWeakReadWriteLock(int paramInt)
  {
    return a(paramInt, a);
  }
  
  public static Striped<Semaphore> lazyWeakSemaphore(int paramInt1, int paramInt2)
  {
    a(paramInt1, new Supplier() {});
  }
  
  public static Striped<Lock> lock(int paramInt)
  {
    new a(paramInt, new Supplier() {}, (byte)0);
  }
  
  public static Striped<ReadWriteLock> readWriteLock(int paramInt)
  {
    return new a(paramInt, a, (byte)0);
  }
  
  public static Striped<Semaphore> semaphore(int paramInt1, int paramInt2)
  {
    new a(paramInt1, new Supplier() {}, (byte)0);
  }
  
  abstract int a(Object paramObject);
  
  public Iterable<L> bulkGet(Iterable<?> paramIterable)
  {
    paramIterable = Iterables.toArray(paramIterable, Object.class);
    if (paramIterable.length == 0) {
      return ImmutableList.of();
    }
    int[] arrayOfInt = new int[paramIterable.length];
    int i = 0;
    while (i < paramIterable.length)
    {
      arrayOfInt[i] = a(paramIterable[i]);
      i += 1;
    }
    Arrays.sort(arrayOfInt);
    int j = arrayOfInt[0];
    paramIterable[0] = getAt(j);
    i = 1;
    if (i < paramIterable.length)
    {
      int k = arrayOfInt[i];
      if (k == j) {
        paramIterable[i] = paramIterable[(i - 1)];
      }
      for (;;)
      {
        i += 1;
        break;
        paramIterable[i] = getAt(k);
        j = k;
      }
    }
    return Collections.unmodifiableList(Arrays.asList(paramIterable));
  }
  
  public abstract L get(Object paramObject);
  
  public abstract L getAt(int paramInt);
  
  public abstract int size();
  
  static final class a<L>
    extends Striped.e<L>
  {
    private final Object[] a;
    
    private a(int paramInt, Supplier<L> paramSupplier)
    {
      super();
      if (paramInt <= 1073741824) {}
      for (boolean bool = true;; bool = false)
      {
        Preconditions.checkArgument(bool, "Stripes must be <= 2^30)");
        this.a = new Object[this.d + 1];
        paramInt = i;
        while (paramInt < this.a.length)
        {
          this.a[paramInt] = paramSupplier.get();
          paramInt += 1;
        }
      }
    }
    
    public final L getAt(int paramInt)
    {
      return (L)this.a[paramInt];
    }
    
    public final int size()
    {
      return this.a.length;
    }
  }
  
  @VisibleForTesting
  static final class b<L>
    extends Striped.e<L>
  {
    final ConcurrentMap<Integer, L> a;
    final Supplier<L> b;
    final int c;
    
    b(int paramInt, Supplier<L> paramSupplier)
    {
      super();
      if (this.d == -1) {}
      for (paramInt = Integer.MAX_VALUE;; paramInt = this.d + 1)
      {
        this.c = paramInt;
        this.b = paramSupplier;
        this.a = new MapMaker().weakValues().makeMap();
        return;
      }
    }
    
    public final L getAt(int paramInt)
    {
      if (this.c != Integer.MAX_VALUE) {
        Preconditions.checkElementIndex(paramInt, size());
      }
      Object localObject = this.a.get(Integer.valueOf(paramInt));
      if (localObject != null) {
        return (L)localObject;
      }
      localObject = this.b.get();
      return (L)MoreObjects.firstNonNull(this.a.putIfAbsent(Integer.valueOf(paramInt), localObject), localObject);
    }
    
    public final int size()
    {
      return this.c;
    }
  }
  
  static final class c
    extends ReentrantLock
  {
    c()
    {
      super();
    }
  }
  
  static final class d
    extends Semaphore
  {
    d(int paramInt)
    {
      super(false);
    }
  }
  
  static abstract class e<L>
    extends Striped<L>
  {
    final int d;
    
    e(int paramInt)
    {
      super();
      if (paramInt > 0) {
        bool = true;
      }
      Preconditions.checkArgument(bool, "Stripes must be positive");
      if (paramInt > 1073741824) {}
      for (paramInt = -1;; paramInt = (1 << IntMath.log2(paramInt, RoundingMode.CEILING)) - 1)
      {
        this.d = paramInt;
        return;
      }
    }
    
    final int a(Object paramObject)
    {
      int i = paramObject.hashCode();
      i ^= i >>> 20 ^ i >>> 12;
      return (i >>> 4 ^ i >>> 7 ^ i) & this.d;
    }
    
    public final L get(Object paramObject)
    {
      return (L)getAt(a(paramObject));
    }
  }
  
  @VisibleForTesting
  static final class f<L>
    extends Striped.e<L>
  {
    final AtomicReferenceArray<a<? extends L>> a;
    final Supplier<L> b;
    final int c;
    final ReferenceQueue<L> e = new ReferenceQueue();
    
    f(int paramInt, Supplier<L> paramSupplier)
    {
      super();
      if (this.d == -1) {}
      for (paramInt = Integer.MAX_VALUE;; paramInt = this.d + 1)
      {
        this.c = paramInt;
        this.a = new AtomicReferenceArray(this.c);
        this.b = paramSupplier;
        return;
      }
    }
    
    public final L getAt(int paramInt)
    {
      if (this.c != Integer.MAX_VALUE) {
        Preconditions.checkElementIndex(paramInt, size());
      }
      a locala1 = (a)this.a.get(paramInt);
      if (locala1 == null) {}
      for (Object localObject1 = null; localObject1 != null; localObject1 = locala1.get()) {
        return (L)localObject1;
      }
      Object localObject2 = this.b.get();
      a locala2 = new a(localObject2, paramInt, this.e);
      while (!this.a.compareAndSet(paramInt, locala1, locala2))
      {
        locala1 = (a)this.a.get(paramInt);
        if (locala1 == null) {}
        for (localObject1 = null; localObject1 != null; localObject1 = locala1.get()) {
          return (L)localObject1;
        }
      }
      for (;;)
      {
        localObject1 = this.e.poll();
        if (localObject1 == null) {
          break;
        }
        localObject1 = (a)localObject1;
        this.a.compareAndSet(((a)localObject1).a, localObject1, null);
      }
      return (L)localObject2;
    }
    
    public final int size()
    {
      return this.c;
    }
    
    static final class a<L>
      extends WeakReference<L>
    {
      final int a;
      
      a(L paramL, int paramInt, ReferenceQueue<L> paramReferenceQueue)
      {
        super(paramReferenceQueue);
        this.a = paramInt;
      }
    }
  }
}


/* Location:              /home/merong/decompile/hackery-dex2jar.jar!/com/google/common/util/concurrent/Striped.class
 * Java compiler version: 6 (50.0)
 * JD-Core Version:       0.7.1
 */