| /***************************************************************** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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. |
| ****************************************************************/ |
| /* |
| * Copyright 2010 Google Inc. All Rights Reserved. |
| * |
| * 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 org.apache.cayenne.util.concurrentlinkedhashmap; |
| |
| import java.util.Collection; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| /** |
| * A common set of {@link Weigher} implementations. |
| * |
| * @author ben.manes@gmail.com (Ben Manes) |
| * @see <a href="https://code.google.com/p/concurrentlinkedhashmap/"> |
| * http://code.google.com/p/concurrentlinkedhashmap/</a> |
| */ |
| final class Weighers { |
| |
| private Weighers() { |
| throw new AssertionError(); |
| } |
| |
| /** |
| * A weigher where a value has a weight of <tt>1</tt>. A map bounded with this weigher |
| * will evict when the number of key-value pairs exceeds the capacity. |
| * |
| * @return A weigher where a value takes one unit of capacity. |
| */ |
| @SuppressWarnings({ |
| "unchecked" |
| }) |
| public static <V> Weigher<V> singleton() { |
| return (Weigher<V>) SingletonWeigher.INSTANCE; |
| } |
| |
| /** |
| * A weigher where the value is a byte array and its weight is the number of bytes. A |
| * map bounded with this weigher will evict when the number of bytes exceeds the |
| * capacity rather than the number of key-value pairs in the map. This allows for |
| * restricting the capacity based on the memory-consumption and is primarily for usage |
| * by dedicated caching servers that hold the serialized data. |
| * <p> |
| * A value with a weight of <tt>0</tt> will be rejected by the map. If a value with |
| * this weight can occur then the caller should eagerly evaluate the value and treat |
| * it as a removal operation. Alternatively, a custom weigher may be specified on the |
| * map to assign an empty value a positive weight. |
| * |
| * @return A weigher where each byte takes one unit of capacity. |
| */ |
| public static Weigher<byte[]> byteArray() { |
| return ByteArrayWeigher.INSTANCE; |
| } |
| |
| /** |
| * A weigher where the value is a {@link Iterable} and its weight is the number of |
| * elements. This weigher only should be used when the alternative |
| * {@link #collection()} weigher cannot be, as evaluation takes O(n) time. A map |
| * bounded with this weigher will evict when the total number of elements exceeds the |
| * capacity rather than the number of key-value pairs in the map. |
| * <p> |
| * A value with a weight of <tt>0</tt> will be rejected by the map. If a value with |
| * this weight can occur then the caller should eagerly evaluate the value and treat |
| * it as a removal operation. Alternatively, a custom weigher may be specified on the |
| * map to assign an empty value a positive weight. |
| * |
| * @return A weigher where each element takes one unit of capacity. |
| */ |
| @SuppressWarnings({ |
| "unchecked" |
| }) |
| public static <E> Weigher<? super Iterable<E>> iterable() { |
| return (Weigher<Iterable<E>>) (Weigher<?>) IterableWeigher.INSTANCE; |
| } |
| |
| /** |
| * A weigher where the value is a {@link Collection} and its weight is the number of |
| * elements. A map bounded with this weigher will evict when the total number of |
| * elements exceeds the capacity rather than the number of key-value pairs in the map. |
| * <p> |
| * A value with a weight of <tt>0</tt> will be rejected by the map. If a value with |
| * this weight can occur then the caller should eagerly evaluate the value and treat |
| * it as a removal operation. Alternatively, a custom weigher may be specified on the |
| * map to assign an empty value a positive weight. |
| * |
| * @return A weigher where each element takes one unit of capacity. |
| */ |
| @SuppressWarnings({ |
| "unchecked" |
| }) |
| public static <E> Weigher<? super Collection<E>> collection() { |
| return (Weigher<Collection<E>>) (Weigher<?>) CollectionWeigher.INSTANCE; |
| } |
| |
| /** |
| * A weigher where the value is a {@link List} and its weight is the number of |
| * elements. A map bounded with this weigher will evict when the total number of |
| * elements exceeds the capacity rather than the number of key-value pairs in the map. |
| * <p> |
| * A value with a weight of <tt>0</tt> will be rejected by the map. If a value with |
| * this weight can occur then the caller should eagerly evaluate the value and treat |
| * it as a removal operation. Alternatively, a custom weigher may be specified on the |
| * map to assign an empty value a positive weight. |
| * |
| * @return A weigher where each element takes one unit of capacity. |
| */ |
| @SuppressWarnings({ |
| "unchecked" |
| }) |
| public static <E> Weigher<? super List<E>> list() { |
| return (Weigher<List<E>>) (Weigher<?>) ListWeigher.INSTANCE; |
| } |
| |
| /** |
| * A weigher where the value is a {@link Set} and its weight is the number of |
| * elements. A map bounded with this weigher will evict when the total number of |
| * elements exceeds the capacity rather than the number of key-value pairs in the map. |
| * <p> |
| * A value with a weight of <tt>0</tt> will be rejected by the map. If a value with |
| * this weight can occur then the caller should eagerly evaluate the value and treat |
| * it as a removal operation. Alternatively, a custom weigher may be specified on the |
| * map to assign an empty value a positive weight. |
| * |
| * @return A weigher where each element takes one unit of capacity. |
| */ |
| @SuppressWarnings({ |
| "unchecked" |
| }) |
| public static <E> Weigher<? super Set<E>> set() { |
| return (Weigher<Set<E>>) (Weigher<?>) SetWeigher.INSTANCE; |
| } |
| |
| /** |
| * A weigher where the value is a {@link Map} and its weight is the number of entries. |
| * A map bounded with this weigher will evict when the total number of entries across |
| * all values exceeds the capacity rather than the number of key-value pairs in the |
| * map. |
| * <p> |
| * A value with a weight of <tt>0</tt> will be rejected by the map. If a value with |
| * this weight can occur then the caller should eagerly evaluate the value and treat |
| * it as a removal operation. Alternatively, a custom weigher may be specified on the |
| * map to assign an empty value a positive weight. |
| * |
| * @return A weigher where each entry takes one unit of capacity. |
| */ |
| @SuppressWarnings({ |
| "unchecked" |
| }) |
| public static <A, B> Weigher<? super Map<A, B>> map() { |
| return (Weigher<Map<A, B>>) (Weigher<?>) MapWeigher.INSTANCE; |
| } |
| |
| private enum SingletonWeigher implements Weigher<Object> { |
| INSTANCE; |
| |
| public int weightOf(Object value) { |
| return 1; |
| } |
| } |
| |
| private enum ByteArrayWeigher implements Weigher<byte[]> { |
| INSTANCE; |
| |
| public int weightOf(byte[] value) { |
| return value.length; |
| } |
| } |
| |
| private enum IterableWeigher implements Weigher<Iterable<?>> { |
| INSTANCE; |
| |
| public int weightOf(Iterable<?> values) { |
| if (values instanceof Collection<?>) { |
| return ((Collection<?>) values).size(); |
| } |
| int size = 0; |
| for (Object value : values) { |
| size++; |
| } |
| return size; |
| } |
| } |
| |
| private enum CollectionWeigher implements Weigher<Collection<?>> { |
| INSTANCE; |
| |
| public int weightOf(Collection<?> values) { |
| return values.size(); |
| } |
| } |
| |
| private enum ListWeigher implements Weigher<List<?>> { |
| INSTANCE; |
| |
| public int weightOf(List<?> values) { |
| return values.size(); |
| } |
| } |
| |
| private enum SetWeigher implements Weigher<Set<?>> { |
| INSTANCE; |
| |
| public int weightOf(Set<?> values) { |
| return values.size(); |
| } |
| } |
| |
| private enum MapWeigher implements Weigher<Map<?, ?>> { |
| INSTANCE; |
| |
| public int weightOf(Map<?, ?> values) { |
| return values.size(); |
| } |
| } |
| } |