{"sources": [ [1, "/*"], [2, " * SonarQube, open source software quality management tool."], [3, " * Copyright (C) 2008-2014 SonarSource"], [4, " * mailto:contact AT sonarsource DOT com"], [5, " *"], [6, " * SonarQube is free software; you can redistribute it and/or"], [7, " * modify it under the terms of the GNU Lesser General Public"], [8, " * License as published by the Free Software Foundation; either"], [9, " * version 3 of the License, or (at your option) any later version."], [10, " *"], [11, " * SonarQube is distributed in the hope that it will be useful,"], [12, " * but WITHOUT ANY WARRANTY; without even the implied warranty of"], [13, " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU"], [14, " * Lesser General Public License for more details."], [15, " *"], [16, " * You should have received a copy of the GNU Lesser General Public License"], [17, " * along with this program; if not, write to the Free Software Foundation,"], [18, " * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA."], [19, " */"], [20, "package org.sonar.batch.index;"], [21, ""], [22, "import com.google.common.collect.Sets;"], [23, "import com.persistit.Exchange;"], [24, "import com.persistit.Key;"], [25, "import com.persistit.KeyFilter;"], [26, "import com.persistit.exception.PersistitException;"], [27, "import org.apache.commons.lang.builder.ToStringBuilder;"], [28, ""], [29, "import javax.annotation.CheckForNull;"], [30, ""], [31, "import java.io.Serializable;"], [32, "import java.util.Iterator;"], [33, "import java.util.NoSuchElementException;"], [34, "import java.util.Set;"], [35, ""], [36, "/**"], [37, " * <p>"], [38, " * This cache is not thread-safe, due to direct usage of {@link com.persistit.Exchange}"], [39, " * </p>"], [40, " */"], [41, "public class Cache<V extends Serializable> {"], [42, ""], [43, " private final String name;"], [44, " private final Exchange exchange;"], [45, ""], [46, " Cache(String name, Exchange exchange) {"], [47, " this.name = name;"], [48, " this.exchange = exchange;"], [49, " }"], [50, ""], [51, " public Cache<V> put(Object key, V value) {"], [52, " resetKey(key);"], [53, " return doPut(value);"], [54, " }"], [55, ""], [56, " public Cache<V> put(Object firstKey, Object secondKey, V value) {"], [57, " resetKey(firstKey, secondKey);"], [58, " return doPut(value);"], [59, " }"], [60, ""], [61, " public Cache<V> put(Object firstKey, Object secondKey, Object thirdKey, V value) {"], [62, " resetKey(firstKey, secondKey, thirdKey);"], [63, " return doPut(value);"], [64, " }"], [65, ""], [66, " public Cache<V> put(Object[] key, V value) {"], [67, " resetKey(key);"], [68, " return doPut(value);"], [69, " }"], [70, ""], [71, " private Cache<V> doPut(V value) {"], [72, " try {"], [73, " exchange.getValue().put(value);"], [74, " exchange.store();"], [75, " return this;"], [76, " } catch (Exception e) {"], [77, " throw new IllegalStateException(\"Fail to put element in the cache \" + name, e);"], [78, " }"], [79, " }"], [80, ""], [81, " /**"], [82, " * Returns the value object associated with keys, or null if not found."], [83, " */"], [84, " public V get(Object key) {"], [85, " resetKey(key);"], [86, " return doGet();"], [87, " }"], [88, ""], [89, " /**"], [90, " * Returns the value object associated with keys, or null if not found."], [91, " */"], [92, " @CheckForNull"], [93, " public V get(Object firstKey, Object secondKey) {"], [94, " resetKey(firstKey, secondKey);"], [95, " return doGet();"], [96, " }"], [97, ""], [98, " /**"], [99, " * Returns the value object associated with keys, or null if not found."], [100, " */"], [101, " @CheckForNull"], [102, " public V get(Object firstKey, Object secondKey, Object thirdKey) {"], [103, " resetKey(firstKey, secondKey, thirdKey);"], [104, " return doGet();"], [105, " }"], [106, ""], [107, " /**"], [108, " * Returns the value object associated with keys, or null if not found."], [109, " */"], [110, " @CheckForNull"], [111, " public V get(Object[] key) {"], [112, " resetKey(key);"], [113, " return doGet();"], [114, " }"], [115, ""], [116, " @SuppressWarnings(\"unchecked\")"], [117, " @CheckForNull"], [118, " private V doGet() {"], [119, " try {"], [120, " exchange.fetch();"], [121, " if (!exchange.getValue().isDefined()) {"], [122, " return null;"], [123, " }"], [124, " return (V) exchange.getValue().get();"], [125, " } catch (Exception e) {"], [126, " // TODO add parameters to message"], [127, " throw new IllegalStateException(\"Fail to get element from cache \" + name, e);"], [128, " }"], [129, " }"], [130, ""], [131, " public boolean containsKey(Object key) {"], [132, " resetKey(key);"], [133, " return doContainsKey();"], [134, " }"], [135, ""], [136, " public boolean containsKey(Object firstKey, Object secondKey) {"], [137, " resetKey(firstKey, secondKey);"], [138, " return doContainsKey();"], [139, " }"], [140, ""], [141, " public boolean containsKey(Object firstKey, Object secondKey, Object thirdKey) {"], [142, " resetKey(firstKey, secondKey, thirdKey);"], [143, " return doContainsKey();"], [144, " }"], [145, ""], [146, " public boolean containsKey(Object[] key) {"], [147, " resetKey(key);"], [148, " return doContainsKey();"], [149, " }"], [150, ""], [151, " private boolean doContainsKey() {"], [152, " try {"], [153, " exchange.fetch();"], [154, " return exchange.isValueDefined();"], [155, " } catch (Exception e) {"], [156, " // TODO add parameters to message"], [157, " throw new IllegalStateException(\"Fail to check if element is in cache \" + name, e);"], [158, " }"], [159, " }"], [160, ""], [161, " public boolean remove(Object key) {"], [162, " resetKey(key);"], [163, " return doRemove();"], [164, " }"], [165, ""], [166, " public boolean remove(Object firstKey, Object secondKey) {"], [167, " resetKey(firstKey, secondKey);"], [168, " return doRemove();"], [169, " }"], [170, ""], [171, " public boolean remove(Object firstKey, Object secondKey, Object thirdKey) {"], [172, " resetKey(firstKey, secondKey, thirdKey);"], [173, " return doRemove();"], [174, " }"], [175, ""], [176, " public boolean remove(Object[] key) {"], [177, " resetKey(key);"], [178, " return doRemove();"], [179, " }"], [180, ""], [181, " private boolean doRemove() {"], [182, " try {"], [183, " return exchange.remove();"], [184, " } catch (Exception e) {"], [185, " // TODO add parameters to message"], [186, " throw new IllegalStateException(\"Fail to get element from cache \" + name, e);"], [187, " }"], [188, " }"], [189, ""], [190, " /**"], [191, " * Removes everything in the specified group."], [192, " *"], [193, " * @param group The group name."], [194, " */"], [195, " public Cache<V> clear(Object key) {"], [196, " resetKey(key);"], [197, " return doClear();"], [198, " }"], [199, ""], [200, " public Cache<V> clear(Object firstKey, Object secondKey) {"], [201, " resetKey(firstKey, secondKey);"], [202, " return doClear();"], [203, " }"], [204, ""], [205, " public Cache<V> clear(Object firstKey, Object secondKey, Object thirdKey) {"], [206, " resetKey(firstKey, secondKey, thirdKey);"], [207, " return doClear();"], [208, " }"], [209, ""], [210, " public Cache<V> clear(Object[] key) {"], [211, " resetKey(key);"], [212, " return doClear();"], [213, " }"], [214, ""], [215, " private Cache<V> doClear() {"], [216, " try {"], [217, " Key to = new Key(exchange.getKey());"], [218, " to.append(Key.AFTER);"], [219, " exchange.removeKeyRange(exchange.getKey(), to);"], [220, " return this;"], [221, " } catch (Exception e) {"], [222, " throw new IllegalStateException(\"Fail to clear values from cache \" + name, e);"], [223, " }"], [224, " }"], [225, ""], [226, " /**"], [227, " * Clears the default as well as all group caches."], [228, " */"], [229, " public void clear() {"], [230, " try {"], [231, " exchange.clear();"], [232, " exchange.removeAll();"], [233, " } catch (Exception e) {"], [234, " throw new IllegalStateException(\"Fail to clear cache\", e);"], [235, " }"], [236, " }"], [237, ""], [238, " /**"], [239, " * Returns the set of cache keys associated with this group."], [240, " * TODO implement a lazy-loading equivalent with Iterator/Iterable"], [241, " *"], [242, " * @param group The group."], [243, " * @return The set of cache keys for this group."], [244, " */"], [245, " @SuppressWarnings(\"rawtypes\")"], [246, " public Set keySet(Object key) {"], [247, " try {"], [248, " Set<Object> keys = Sets.newLinkedHashSet();"], [249, " exchange.clear();"], [250, " Exchange iteratorExchange = new Exchange(exchange);"], [251, " iteratorExchange.append(key);"], [252, " iteratorExchange.append(Key.BEFORE);"], [253, " while (iteratorExchange.next(false)) {"], [254, " keys.add(iteratorExchange.getKey().indexTo(-1).decode());"], [255, " }"], [256, " return keys;"], [257, " } catch (Exception e) {"], [258, " throw new IllegalStateException(\"Fail to get keys from cache \" + name, e);"], [259, " }"], [260, " }"], [261, ""], [262, " @SuppressWarnings(\"rawtypes\")"], [263, " public Set keySet(Object firstKey, Object secondKey) {"], [264, " try {"], [265, " Set<Object> keys = Sets.newLinkedHashSet();"], [266, " exchange.clear();"], [267, " Exchange iteratorExchange = new Exchange(exchange);"], [268, " iteratorExchange.append(firstKey);"], [269, " iteratorExchange.append(secondKey);"], [270, " iteratorExchange.append(Key.BEFORE);"], [271, " while (iteratorExchange.next(false)) {"], [272, " keys.add(iteratorExchange.getKey().indexTo(-1).decode());"], [273, " }"], [274, " return keys;"], [275, " } catch (Exception e) {"], [276, " throw new IllegalStateException(\"Fail to get keys from cache \" + name, e);"], [277, " }"], [278, " }"], [279, ""], [280, " /**"], [281, " * Returns the set of keys associated with this cache."], [282, " *"], [283, " * @return The set containing the keys for this cache."], [284, " */"], [285, " public Set<Object> keySet() {"], [286, " try {"], [287, " Set<Object> keys = Sets.newLinkedHashSet();"], [288, " exchange.clear();"], [289, " Exchange iteratorExchange = new Exchange(exchange);"], [290, " iteratorExchange.append(Key.BEFORE);"], [291, " while (iteratorExchange.next(false)) {"], [292, " keys.add(iteratorExchange.getKey().indexTo(-1).decode());"], [293, " }"], [294, " return keys;"], [295, " } catch (Exception e) {"], [296, " throw new IllegalStateException(\"Fail to get keys from cache \" + name, e);"], [297, " }"], [298, " }"], [299, ""], [300, " /**"], [301, " * Lazy-loading values for given keys"], [302, " */"], [303, " public Iterable<V> values(Object firstKey, Object secondKey) {"], [304, " try {"], [305, " exchange.clear();"], [306, " exchange.append(firstKey).append(secondKey).append(Key.BEFORE);"], [307, " Exchange iteratorExchange = new Exchange(exchange);"], [308, " KeyFilter filter = new KeyFilter().append(KeyFilter.simpleTerm(firstKey)).append(KeyFilter.simpleTerm(secondKey));"], [309, " return new ValueIterable<V>(iteratorExchange, filter);"], [310, " } catch (Exception e) {"], [311, " throw failToGetValues(e);"], [312, " }"], [313, " }"], [314, ""], [315, " private IllegalStateException failToGetValues(Exception e) {"], [316, " return new IllegalStateException(\"Fail to get values from cache \" + name, e);"], [317, " }"], [318, ""], [319, " /**"], [320, " * Lazy-loading values for a given key"], [321, " */"], [322, " public Iterable<V> values(Object firstKey) {"], [323, " try {"], [324, " exchange.clear();"], [325, " exchange.append(firstKey).append(Key.BEFORE);"], [326, " Exchange iteratorExchange = new Exchange(exchange);"], [327, " KeyFilter filter = new KeyFilter().append(KeyFilter.simpleTerm(firstKey));"], [328, " return new ValueIterable<V>(iteratorExchange, filter);"], [329, " } catch (Exception e) {"], [330, " throw failToGetValues(e);"], [331, " }"], [332, " }"], [333, ""], [334, " /**"], [335, " * Lazy-loading values"], [336, " */"], [337, " public Iterable<V> values() {"], [338, " try {"], [339, " exchange.clear().append(Key.BEFORE);"], [340, " Exchange iteratorExchange = new Exchange(exchange);"], [341, " KeyFilter filter = new KeyFilter().append(KeyFilter.ALL);"], [342, " return new ValueIterable<V>(iteratorExchange, filter);"], [343, " } catch (Exception e) {"], [344, " throw failToGetValues(e);"], [345, " }"], [346, " }"], [347, ""], [348, " public Iterable<Entry<V>> entries() {"], [349, " exchange.clear().to(Key.BEFORE);"], [350, " KeyFilter filter = new KeyFilter().append(KeyFilter.ALL);"], [351, " return new EntryIterable<V>(new Exchange(exchange), filter);"], [352, " }"], [353, ""], [354, " public Iterable<Entry<V>> entries(Object firstKey) {"], [355, " exchange.clear().append(firstKey).append(Key.BEFORE);"], [356, " KeyFilter filter = new KeyFilter().append(KeyFilter.simpleTerm(firstKey));"], [357, " return new EntryIterable<V>(new Exchange(exchange), filter);"], [358, " }"], [359, ""], [360, " private void resetKey(Object key) {"], [361, " exchange.clear();"], [362, " exchange.append(key);"], [363, " }"], [364, ""], [365, " private void resetKey(Object first, Object second) {"], [366, " exchange.clear();"], [367, " exchange.append(first).append(second);"], [368, " }"], [369, ""], [370, " private void resetKey(Object first, Object second, Object third) {"], [371, " exchange.clear();"], [372, " exchange.append(first).append(second).append(third);"], [373, " }"], [374, ""], [375, " private void resetKey(Object[] keys) {"], [376, " exchange.clear();"], [377, " for (Object o : keys) {"], [378, " exchange.append(o);"], [379, " }"], [380, " }"], [381, ""], [382, " //"], [383, " // LAZY ITERATORS AND ITERABLES"], [384, " //"], [385, ""], [386, " private static class ValueIterable<T extends Serializable> implements Iterable<T> {"], [387, " private final Iterator<T> iterator;"], [388, ""], [389, " private ValueIterable(Exchange exchange, KeyFilter keyFilter) {"], [390, " this.iterator = new ValueIterator<T>(exchange, keyFilter);"], [391, " }"], [392, ""], [393, " @Override"], [394, " public Iterator<T> iterator() {"], [395, " return iterator;"], [396, " }"], [397, " }"], [398, ""], [399, " private static class ValueIterator<T extends Serializable> implements Iterator<T> {"], [400, " private final Exchange exchange;"], [401, " private final KeyFilter keyFilter;"], [402, ""], [403, " private ValueIterator(Exchange exchange, KeyFilter keyFilter) {"], [404, " this.exchange = exchange;"], [405, " this.keyFilter = keyFilter;"], [406, " }"], [407, ""], [408, " @Override"], [409, " public boolean hasNext() {"], [410, " try {"], [411, " return exchange.hasNext(keyFilter);"], [412, " } catch (PersistitException e) {"], [413, " throw new IllegalStateException(e);"], [414, " }"], [415, " }"], [416, ""], [417, " @SuppressWarnings(\"unchecked\")"], [418, " @Override"], [419, " public T next() {"], [420, " try {"], [421, " exchange.next(keyFilter);"], [422, " } catch (PersistitException e) {"], [423, " throw new IllegalStateException(e);"], [424, " }"], [425, " if (exchange.getValue().isDefined()) {"], [426, " return (T) exchange.getValue().get();"], [427, " }"], [428, " throw new NoSuchElementException();"], [429, " }"], [430, ""], [431, " @Override"], [432, " public void remove() {"], [433, " throw new UnsupportedOperationException(\"Removing an item is not supported\");"], [434, " }"], [435, " }"], [436, ""], [437, " private static class EntryIterable<T extends Serializable> implements Iterable<Entry<T>> {"], [438, " private final EntryIterator<T> it;"], [439, ""], [440, " private EntryIterable(Exchange exchange, KeyFilter keyFilter) {"], [441, " it = new EntryIterator<T>(exchange, keyFilter);"], [442, " }"], [443, ""], [444, " @Override"], [445, " public Iterator<Entry<T>> iterator() {"], [446, " return it;"], [447, " }"], [448, " }"], [449, ""], [450, " private static class EntryIterator<T extends Serializable> implements Iterator<Entry<T>> {"], [451, " private final Exchange exchange;"], [452, " private final KeyFilter keyFilter;"], [453, ""], [454, " private EntryIterator(Exchange exchange, KeyFilter keyFilter) {"], [455, " this.exchange = exchange;"], [456, " this.keyFilter = keyFilter;"], [457, " }"], [458, ""], [459, " @Override"], [460, " public boolean hasNext() {"], [461, " try {"], [462, " return exchange.hasNext(keyFilter);"], [463, " } catch (PersistitException e) {"], [464, " throw new IllegalStateException(e);"], [465, " }"], [466, " }"], [467, ""], [468, " @SuppressWarnings(\"unchecked\")"], [469, " @Override"], [470, " public Entry<T> next() {"], [471, " try {"], [472, " exchange.next(keyFilter);"], [473, " } catch (PersistitException e) {"], [474, " throw new IllegalStateException(e);"], [475, " }"], [476, " if (exchange.getValue().isDefined()) {"], [477, " T value = (T) exchange.getValue().get();"], [478, " Key key = exchange.getKey();"], [479, " Object[] array = new Object[key.getDepth()];"], [480, " for (int i = 0; i < key.getDepth(); i++) {"], [481, " array[i] = key.indexTo(i - key.getDepth()).decode();"], [482, " }"], [483, " return new Entry<T>(array, value);"], [484, " }"], [485, " throw new NoSuchElementException();"], [486, " }"], [487, ""], [488, " @Override"], [489, " public void remove() {"], [490, " throw new UnsupportedOperationException(\"Removing an item is not supported\");"], [491, " }"], [492, " }"], [493, ""], [494, " public static class Entry<V extends Serializable> {"], [495, " private final Object[] key;"], [496, " private final V value;"], [497, ""], [498, " Entry(Object[] key, V value) {"], [499, " this.key = key;"], [500, " this.value = value;"], [501, " }"], [502, ""], [503, " public Object[] key() {"], [504, " return key;"], [505, " }"], [506, ""], [507, " @CheckForNull"], [508, " public V value() {"], [509, " return value;"], [510, " }"], [511, ""], [512, " @Override"], [513, " public String toString() {"], [514, " return ToStringBuilder.reflectionToString(this);"], [515, " }"], [516, " }"], [517, ""], [518, "}"], [519, ""] ]}