merge with branch issue-345

This commit is contained in:
Sebastian Sdorra
2013-03-27 08:53:22 +01:00
41 changed files with 4415 additions and 181 deletions

View File

@@ -0,0 +1,95 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.io;
//~--- JDK imports ------------------------------------------------------------
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* Utility for making deep copies (vs. clone()'s shallow copies) of
* objects. Objects are first serialized and then deserialized. Error
* checking is fairly minimal in this implementation. If an object is
* encountered that cannot be serialized (or that references an object
* that cannot be serialized) an error is printed to System.err and
* null is returned. Depending on your specific application, it might
* make more sense to have copy(...) re-throw the exception.
*
* @author Sebastian Sdorra
* @since 1.29
* @see http://javatechniques.com/blog/faster-deep-copies-of-java-objects
*/
public final class DeepCopy
{
/**
* Returns a copy of the object, or null if the object cannot
* be serialized.
*
* @param orig
* @param <T>
*
* @return
*
* @throws IOException
*/
public static <T> T copy(T orig) throws IOException
{
T obj = null;
try
{
// Write the object out to a byte array
FastByteArrayOutputStream fbos = new FastByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(fbos);
out.writeObject(orig);
out.flush();
out.close();
// Retrieve an input stream from the byte array and read
// a copy of the object back in.
ObjectInputStream in = new ObjectInputStream(fbos.getInputStream());
obj = (T) in.readObject();
}
catch (Exception ex)
{
throw new IOException("could not copy object", ex);
}
return obj;
}
}

View File

@@ -0,0 +1,161 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.io;
//~--- JDK imports ------------------------------------------------------------
import java.io.InputStream;
/**
* ByteArrayInputStream implementation that does not synchronize methods.
*
* @author Sebastian Sdorra
* @since 1.29
* @see http://javatechniques.com/blog/faster-deep-copies-of-java-objects
*/
public final class FastByteArrayInputStream extends InputStream
{
/**
* Constructs ...
*
*
* @param buf
* @param count
*/
public FastByteArrayInputStream(byte[] buf, int count)
{
this.buf = buf;
this.count = count;
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@Override
public final int available()
{
return count - pos;
}
/**
* Method description
*
*
* @return
*/
@Override
public final int read()
{
return (pos < count)
? (buf[pos++] & 0xff)
: -1;
}
/**
* Method description
*
*
* @param b
* @param off
* @param len
*
* @return
*/
@Override
public final int read(byte[] b, int off, int len)
{
if (pos >= count)
{
return -1;
}
if ((pos + len) > count)
{
len = (count - pos);
}
System.arraycopy(buf, pos, b, off, len);
pos += len;
return len;
}
/**
* Method description
*
*
* @param n
*
* @return
*/
@Override
public final long skip(long n)
{
if ((pos + n) > count)
{
n = count - pos;
}
if (n < 0)
{
return 0;
}
pos += n;
return n;
}
//~--- fields ---------------------------------------------------------------
/**
* Our byte buffer
*/
private byte[] buf = null;
/**
* Number of bytes that we can read from the buffer
*/
private int count = 0;
/**
* Number of bytes that have been read from the buffer
*/
private int pos = 0;
}

View File

@@ -0,0 +1,187 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.io;
//~--- JDK imports ------------------------------------------------------------
import java.io.InputStream;
import java.io.OutputStream;
/**
* ByteArrayOutputStream implementation that doesn't synchronize methods
* and doesn't copy the data on toByteArray().
*
* @author Sebastian Sdorra
* @since 1.29
* @see http://javatechniques.com/blog/faster-deep-copies-of-java-objects
*/
public final class FastByteArrayOutputStream extends OutputStream
{
/**
* Constructs a stream with buffer capacity size 5K
*/
public FastByteArrayOutputStream()
{
this(5 * 1024);
}
/**
* Constructs a stream with the given initial size
*
* @param initSize
*/
public FastByteArrayOutputStream(int initSize)
{
this.size = 0;
this.buf = new byte[initSize];
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param b
*/
@Override
public final void write(byte b[])
{
verifyBufferSize(size + b.length);
System.arraycopy(b, 0, buf, size, b.length);
size += b.length;
}
/**
* Method description
*
*
* @param b
* @param off
* @param len
*/
@Override
public final void write(byte b[], int off, int len)
{
verifyBufferSize(size + len);
System.arraycopy(b, off, buf, size, len);
size += len;
}
/**
* Method description
*
*
* @param b
*/
@Override
public final void write(int b)
{
verifyBufferSize(size + 1);
buf[size++] = (byte) b;
}
/**
* Method description
*
*/
public void reset()
{
size = 0;
}
//~--- get methods ----------------------------------------------------------
/**
* Returns the byte array containing the written data. Note that this
* array will almost always be larger than the amount of data actually
* written.
*
* @return
*/
public byte[] getByteArray()
{
return buf;
}
/**
* Returns a ByteArrayInputStream for reading back the written data
*
* @return
*/
public InputStream getInputStream()
{
return new FastByteArrayInputStream(buf, size);
}
/**
* Method description
*
*
* @return
*/
public int getSize()
{
return size;
}
//~--- methods --------------------------------------------------------------
/**
* Ensures that we have a large enough buffer for the given size.
*
* @param sz
*/
private void verifyBufferSize(int sz)
{
if (sz > buf.length)
{
byte[] old = buf;
buf = new byte[Math.max(sz, 2 * buf.length)];
System.arraycopy(old, 0, buf, 0, old.length);
old = null;
}
}
//~--- fields ---------------------------------------------------------------
/**
* Buffer and size
*/
private byte[] buf = null;
/** Field description */
private int size = 0;
}

View File

@@ -33,6 +33,10 @@
package sonia.scm.repository;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.base.Objects;
//~--- JDK imports ------------------------------------------------------------
import java.io.Serializable;
@@ -83,6 +87,45 @@ public class ChangesetPagingResult implements Iterable<Changeset>, Serializable
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param obj
*
* @return
*/
@Override
public boolean equals(Object obj)
{
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
final ChangesetPagingResult other = (ChangesetPagingResult) obj;
return Objects.equal(changesets, other.changesets)
&& Objects.equal(total, other.total);
}
/**
* Method description
*
*
* @return
*/
@Override
public int hashCode()
{
return Objects.hashCode(changesets, total);
}
/**
* Returns an iterator which can iterate over the current list of changesets.
*
@@ -103,6 +146,23 @@ public class ChangesetPagingResult implements Iterable<Changeset>, Serializable
return it;
}
/**
* Method description
*
*
* @return
*/
@Override
public String toString()
{
//J-
return Objects.toStringHelper(this)
.add("changesets", changesets)
.add("total", total)
.toString();
//J+
}
//~--- get methods ----------------------------------------------------------
/**

View File

@@ -77,11 +77,14 @@ public final class LogCommandRequest implements Serializable, Resetable
final LogCommandRequest other = (LogCommandRequest) obj;
//J-
return Objects.equal(startChangeset, other.startChangeset)
&& Objects.equal(endChangeset, other.endChangeset)
&& Objects.equal(pagingStart, other.pagingStart)
&& Objects.equal(pagingLimit, other.pagingLimit)
&& Objects.equal(path, other.path) && Objects.equal(branch, other.branch);
&& Objects.equal(path, other.path)
&& Objects.equal(branch, other.branch);
//J+
}
/**

View File

@@ -212,9 +212,10 @@ public class GitChangesetConverter implements Closeable
Collection<String> tagCollection = tags.get(commit.getId());
if (tagCollection != null)
if (Util.isNotEmpty(tagCollection))
{
changeset.getTags().addAll(tagCollection);
// create a copy of the tag collection to reduce memory on caching
changeset.getTags().addAll(Lists.newArrayList(tagCollection));
}
changeset.setBranches(branches);

View File

@@ -142,6 +142,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import sonia.scm.cache.GuavaCacheManager;
/**
*
@@ -272,8 +273,8 @@ public class ScmServletModule extends ServletModule
bind(WebSecurityContext.class).to(BasicSecurityContext.class);
bind(AdministrationContext.class, DefaultAdministrationContext.class);
// bind security cache
bind(CacheManager.class, EhCacheManager.class);
// bind cache
bind(CacheManager.class, GuavaCacheManager.class);
// bind dao
bind(GroupDAO.class, XmlGroupDAO.class);

View File

@@ -0,0 +1,116 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.cache;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.collect.Iterators;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//~--- JDK imports ------------------------------------------------------------
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Iterator;
/**
*
* @author Sebastian Sdorra
*/
public final class CacheConfigurations
{
/**
* the logger for CacheConfigurations
*/
private static final Logger logger =
LoggerFactory.getLogger(CacheConfigurations.class);
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*/
private CacheConfigurations() {}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param loadingClass
* @param resource
*
* @return
*/
public static Iterator<URL> findModuleResources(Class<?> loadingClass,
String resource)
{
Iterator<URL> it = null;
try
{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader == null)
{
classLoader = loadingClass.getClassLoader();
}
Enumeration<URL> enm = classLoader.getResources(resource);
if (enm != null)
{
it = Iterators.forEnumeration(enm);
}
}
catch (IOException ex)
{
logger.error("could not read module resources", ex);
}
if (it == null)
{
it = Iterators.emptyIterator();
}
return it;
}
}

View File

@@ -0,0 +1,85 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.cache;
/**
*
* @author Sebastian Sdorra
*/
public class CacheException extends RuntimeException
{
/** Field description */
private static final long serialVersionUID = -1108209749696572319L;
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*/
public CacheException() {}
/**
* Constructs ...
*
*
* @param message
*/
public CacheException(String message)
{
super(message);
}
/**
* Constructs ...
*
*
* @param cause
*/
public CacheException(Throwable cause)
{
super(cause);
}
/**
* Constructs ...
*
*
* @param message
* @param cause
*/
public CacheException(String message, Throwable cause)
{
super(message, cause);
}
}

View File

@@ -0,0 +1,147 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.cache;
//~--- non-JDK imports --------------------------------------------------------
import sonia.scm.io.DeepCopy;
//~--- JDK imports ------------------------------------------------------------
import java.io.IOException;
import java.util.Locale;
/**
*
* @author Sebastian Sdorra
*/
public enum CopyStrategy
{
NONE(false, false), READ(true, false), WRITE(false, true),
READWRITE(true, true);
/**
* Constructs ...
*
*
* @param copyOnRead
* @param copyOnWrite
*/
private CopyStrategy(boolean copyOnRead, boolean copyOnWrite)
{
this.copyOnRead = copyOnRead;
this.copyOnWrite = copyOnWrite;
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param value
*
* @return
*/
public static CopyStrategy fromString(String value)
{
return valueOf(value.toUpperCase(Locale.ENGLISH).replace("-", ""));
}
/**
* Method description
*
*
* @param object
* @param <T>
*
* @return
*/
public <T> T copyOnRead(T object)
{
return copyOnRead
? deepCopy(object)
: object;
}
/**
* Method description
*
*
* @param object
* @param <T>
*
* @return
*/
public <T> T copyOnWrite(T object)
{
return copyOnWrite
? deepCopy(object)
: object;
}
/**
* Method description
*
*
* @param object
* @param <T>
*
* @return
*/
private <T> T deepCopy(T object)
{
T copy = null;
try
{
copy = DeepCopy.copy(object);
}
catch (IOException ex)
{
throw new CacheException(
"could not create a copy of ".concat(object.toString()), ex);
}
return copy;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private boolean copyOnRead;
/** Field description */
private boolean copyOnWrite;
}

View File

@@ -35,6 +35,8 @@ package sonia.scm.cache;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.annotations.VisibleForTesting;
import net.sf.ehcache.Element;
import org.slf4j.Logger;
@@ -186,6 +188,18 @@ public class EhCache<K, V> implements Cache<K, V>
return value;
}
/**
* Method description
*
*
* @return
*/
@VisibleForTesting
net.sf.ehcache.Cache getCacheImplementation()
{
return cache;
}
//~--- fields ---------------------------------------------------------------
/** Field description */

View File

@@ -0,0 +1,475 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.cache;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Objects;
import com.google.common.collect.Maps;
import com.google.common.io.Closeables;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import sonia.scm.SCMContext;
//~--- JDK imports ------------------------------------------------------------
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
/**
*
* @author Sebastian Sdorra
*/
public class EhCacheConfigurationReader
{
/** Field description */
private static final String ATTRIBUTE_NAME = "name";
/** Field description */
private static final String DEFAULT = "/config/ehcache.xml";
/** Field description */
private static final String MANUAL_RESOURCE =
"ext".concat(File.separator).concat("ehcache.xml");
/** Field description */
private static final String MODULE_RESOURCES = "/META-INF/scm/ehcache.xml";
/**
* the logger for EhCacheConfigurationReader
*/
private static final Logger logger =
LoggerFactory.getLogger(EhCacheConfigurationReader.class);
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*/
public EhCacheConfigurationReader()
{
try
{
builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
}
catch (ParserConfigurationException ex)
{
throw new RuntimeException("could not create document builder", ex);
}
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @return
*/
public InputStream read()
{
URL defaultConfig = getDefaultResource();
if (defaultConfig == null)
{
throw new IllegalStateException(
"could not find default cache configuration");
}
readConfiguration(defaultConfig, true);
Iterator<URL> it = getModuleResources();
while (it.hasNext())
{
readConfiguration(it.next(), false);
}
File manualFile = getManualFileResource();
if (manualFile.exists())
{
try
{
readConfiguration(manualFile.toURI().toURL(), false);
}
catch (MalformedURLException ex)
{
logger.error("malformed url", ex);
}
}
else
{
logger.warn("could not find manual configuration at {}", manualFile);
}
Document doc = createMergedConfiguration();
return createInputStream(doc);
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param path
*
* @return
*/
@VisibleForTesting
protected URL getDefaultResource()
{
return EhCacheConfigurationReader.class.getResource(DEFAULT);
}
/**
* Method description
*
*
* @return
*/
@VisibleForTesting
protected File getManualFileResource()
{
return new File(SCMContext.getContext().getBaseDirectory(),
MANUAL_RESOURCE);
}
/**
* Method description
*
*
* @param path
*
* @return
*/
@VisibleForTesting
protected Iterator<URL> getModuleResources()
{
return CacheConfigurations.findModuleResources(
EhCacheConfigurationReader.class, MODULE_RESOURCES);
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param doc
*
* @return
*/
private InputStream createInputStream(Document doc)
{
InputStream stream;
Transformer transformer;
try
{
transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
transformer.transform(new DOMSource(doc), new StreamResult(baos));
if (logger.isTraceEnabled())
{
logger.trace("effective ehcache configuration: {}", baos.toString());
}
stream = new ByteArrayInputStream(baos.toByteArray());
}
catch (Exception ex)
{
throw new IllegalStateException("could not create transformer", ex);
}
return stream;
}
/**
* Method description
*
*
* @return
*/
private Document createMergedConfiguration()
{
Document merged = builder.newDocument();
Element rootEl = merged.createElementNS("http://ehcache.org/ehcache.xsd",
"ehcache");
for (Attr attribute : attributeMap.values())
{
Attr mergedAttr = (Attr) merged.adoptNode(attribute);
rootEl.setAttributeNode(mergedAttr);
}
for (Node node : nodeMap.values())
{
Node mergedNode = merged.adoptNode(node);
rootEl.appendChild(mergedNode);
}
merged.appendChild(rootEl);
return merged;
}
/**
* Method description
*
*
* @param url
* @param throwException
*/
private void readConfiguration(URL url, boolean throwException)
{
logger.debug("read cache configuration from url {}", url.toExternalForm());
InputStream stream = null;
try
{
stream = url.openStream();
Document document = builder.parse(stream);
Element rootEl = document.getDocumentElement();
readConfiguration(rootEl);
}
catch (Exception ex)
{
if (throwException)
{
throw new RuntimeException(
"could not read configuration at ".concat(url.toExternalForm()), ex);
}
else
{
logger.warn("could not read configuration at {}", url.toExternalForm());
}
}
finally
{
Closeables.closeQuietly(stream);
}
}
/**
* Method description
*
*
* @param rootEl
*/
private void readConfiguration(Element rootEl)
{
NamedNodeMap attributes = rootEl.getAttributes();
for (int i = 0; i < attributes.getLength(); i++)
{
Node node = attributes.item(i);
if (Node.ATTRIBUTE_NODE == node.getNodeType())
{
String name = node.getNodeName();
if (!name.startsWith("xmlns") && (node instanceof Attr))
{
attributeMap.put(node.getNodeName(), (Attr) node);
}
}
}
NodeList list = rootEl.getChildNodes();
for (int i = 0; i < list.getLength(); i++)
{
Node node = list.item(i);
if (Node.ELEMENT_NODE == node.getNodeType())
{
String element = node.getNodeName();
String name = null;
Node nameNode = node.getAttributes().getNamedItem(ATTRIBUTE_NAME);
if (nameNode != null)
{
name = nameNode.getNodeValue();
}
nodeMap.put(new Id(element, name), node);
}
}
}
//~--- inner classes --------------------------------------------------------
/**
* Class description
*
*
* @version Enter version here..., 13/03/19
* @author Enter your name here...
*/
private static class Id
{
/**
* Constructs ...
*
*
* @param element
* @param name
*/
public Id(String element, String name)
{
this.element = element;
this.name = name;
}
//~--- methods ------------------------------------------------------------
/**
* Method description
*
*
* @param obj
*
* @return
*/
@Override
public boolean equals(Object obj)
{
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
final Id other = (Id) obj;
return Objects.equal(element, other.element)
&& Objects.equal(name, other.name);
}
/**
* Method description
*
*
* @return
*/
@Override
public int hashCode()
{
return Objects.hashCode(element, name);
}
/**
* Method description
*
*
* @return
*/
@Override
public String toString()
{
//J-
return Objects.toStringHelper(this)
.add("element", element)
.add("name", name)
.toString();
//J+
}
//~--- fields -------------------------------------------------------------
/** Field description */
private String element;
/** Field description */
private String name;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private DocumentBuilder builder;
/** Field description */
private Map<Id, Node> nodeMap = Maps.newLinkedHashMap();
/** Field description */
private Map<String, Attr> attributeMap = Maps.newLinkedHashMap();
}

View File

@@ -35,6 +35,7 @@ package sonia.scm.cache;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.io.Closeables;
import com.google.inject.Singleton;
import org.slf4j.Logger;
@@ -43,6 +44,7 @@ import org.slf4j.LoggerFactory;
//~--- JDK imports ------------------------------------------------------------
import java.io.IOException;
import java.io.InputStream;
/**
*
@@ -67,8 +69,20 @@ public class EhCacheManager implements CacheManager
*/
public EhCacheManager()
{
cacheManager =
new net.sf.ehcache.CacheManager(EhCacheManager.class.getResource(CONFIG));
InputStream stream = null;
try
{
EhCacheConfigurationReader reader = new EhCacheConfigurationReader();
stream = reader.read();
cacheManager = new net.sf.ehcache.CacheManager(stream);
}
finally
{
Closeables.closeQuietly(stream);
}
}
/**
@@ -111,7 +125,8 @@ public class EhCacheManager implements CacheManager
* @return
*/
@Override
public <K, V> Cache<K, V> getCache(Class<K> key, Class<V> value, String name)
public synchronized <K, V> Cache<K, V> getCache(Class<K> key, Class<V> value,
String name)
{
net.sf.ehcache.Cache c = cacheManager.getCache(name);

View File

@@ -0,0 +1,236 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.cache;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.Filter;
//~--- JDK imports ------------------------------------------------------------
import java.util.Set;
/**
*
* @author Sebastian Sdorra
*
* @param <K>
* @param <V>
*/
public class GuavaCache<K, V> implements Cache<K, V>
{
/**
* the logger for GuavaCache
*/
private static final Logger logger =
LoggerFactory.getLogger(GuavaCache.class);
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*
* @param configuration
*/
public GuavaCache(GuavaNamedCacheConfiguration configuration)
{
this(configuration, configuration.getName());
}
/**
* Constructs ...
*
*
* @param configuration
* @param name
*/
public GuavaCache(GuavaCacheConfiguration configuration, String name)
{
this(GuavaCaches.create(configuration, name),
configuration.getCopyStrategy(), name);
}
/**
* Constructs ...
*
*
* @param cache
* @param copyStrategy
* @param name
*/
@VisibleForTesting
protected GuavaCache(com.google.common.cache.Cache<K, V> cache,
CopyStrategy copyStrategy, String name)
{
this.cache = cache;
this.name = name;
if (copyStrategy != null)
{
this.copyStrategy = copyStrategy;
}
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*/
@Override
public void clear()
{
if (logger.isDebugEnabled())
{
logger.debug("clear cache {}", name);
}
cache.invalidateAll();
}
/**
* Method description
*
*
* @param key
*
* @return
*/
@Override
public boolean contains(K key)
{
return cache.getIfPresent(key) != null;
}
/**
* Method description
*
*
* @param key
* @param value
*/
@Override
public void put(K key, V value)
{
cache.put(key, copyStrategy.copyOnWrite(value));
}
/**
* Method description
*
*
* @param key
*
* @return
*/
@Override
public boolean remove(K key)
{
cache.invalidate(key);
return true;
}
/**
* Method description
*
*
* @param filter
*
* @return
*/
@Override
public boolean removeAll(Filter<K> filter)
{
Set<K> keysToRemove = Sets.newHashSet();
for (K key : cache.asMap().keySet())
{
if (filter.accept(key))
{
keysToRemove.add(key);
}
}
boolean result = false;
if (!keysToRemove.isEmpty())
{
cache.invalidateAll(keysToRemove);
result = true;
}
return result;
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param key
*
* @return
*/
@Override
public V get(K key)
{
V value = cache.getIfPresent(key);
if (value != null)
{
value = copyStrategy.copyOnRead(value);
}
return value;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private com.google.common.cache.Cache<K, V> cache;
/** Field description */
private CopyStrategy copyStrategy = CopyStrategy.NONE;
/** Field description */
private String name;
}

View File

@@ -0,0 +1,223 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.cache;
//~--- JDK imports ------------------------------------------------------------
import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
/**
*
* @author Sebastian Sdorra
*/
@XmlRootElement(name = "cache")
@XmlAccessorType(XmlAccessType.FIELD)
public class GuavaCacheConfiguration implements Serializable
{
/** Field description */
private static final long serialVersionUID = -8734373158089010603L;
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
public Integer getConcurrencyLevel()
{
return concurrencyLevel;
}
/**
* Method description
*
*
* @return
*/
public CopyStrategy getCopyStrategy()
{
return copyStrategy;
}
/**
* Method description
*
*
* @return
*/
public Long getExpireAfterAccess()
{
return expireAfterAccess;
}
/**
* Method description
*
*
* @return
*/
public Long getExpireAfterWrite()
{
return expireAfterWrite;
}
/**
* Method description
*
*
* @return
*/
public Integer getInitialCapacity()
{
return initialCapacity;
}
/**
* Method description
*
*
* @return
*/
public Long getMaximumSize()
{
return maximumSize;
}
/**
* Method description
*
*
* @return
*/
public Long getMaximumWeight()
{
return maximumWeight;
}
/**
* Method description
*
*
* @return
*/
public Boolean getRecordStats()
{
return recordStats;
}
/**
* Method description
*
*
* @return
*/
public Boolean getSoftValues()
{
return softValues;
}
/**
* Method description
*
*
* @return
*/
public Boolean getWeakKeys()
{
return weakKeys;
}
/**
* Method description
*
*
* @return
*/
public Boolean getWeakValues()
{
return weakValues;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
@XmlAttribute
private Integer concurrencyLevel;
/** Field description */
@XmlAttribute
private CopyStrategy copyStrategy;
/** Field description */
@XmlAttribute
private Long expireAfterAccess;
/** Field description */
@XmlAttribute
private Long expireAfterWrite;
/** Field description */
@XmlAttribute
private Integer initialCapacity;
/** Field description */
@XmlAttribute
private Long maximumSize;
/** Field description */
@XmlAttribute
private Long maximumWeight;
/** Field description */
@XmlAttribute
private Boolean recordStats;
/** Field description */
@XmlAttribute
private Boolean softValues;
/** Field description */
@XmlAttribute
private Boolean weakKeys;
/** Field description */
@XmlAttribute
private Boolean weakValues;
}

View File

@@ -0,0 +1,308 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.cache;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.SCMContext;
//~--- JDK imports ------------------------------------------------------------
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
/**
*
* @author Sebastian Sdorra
*/
public class GuavaCacheConfigurationReader
{
/** Field description */
private static final String DEFAULT = "/config/gcache.xml";
/** Field description */
private static final String MANUAL_RESOURCE =
"ext".concat(File.separator).concat("gcache.xml");
/** Field description */
private static final String MODULE_RESOURCES = "/META-INF/scm/gcache.xml";
/**
* the logger for CacheConfigurationReader
*/
private static final Logger logger =
LoggerFactory.getLogger(GuavaCacheConfigurationReader.class);
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*/
private GuavaCacheConfigurationReader()
{
try
{
this.context =
JAXBContext.newInstance(GuavaCacheManagerConfiguration.class);
}
catch (JAXBException ex)
{
throw new CacheException(
"could not create jaxb context for cache configuration", ex);
}
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @return
*/
public static GuavaCacheManagerConfiguration read()
{
return new GuavaCacheConfigurationReader().doRead();
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@VisibleForTesting
protected URL getDefaultResource()
{
return GuavaCacheConfigurationReader.class.getResource(DEFAULT);
}
/**
* Method description
*
*
* @return
*/
@VisibleForTesting
protected File getManualFileResource()
{
return new File(SCMContext.getContext().getBaseDirectory(),
MANUAL_RESOURCE);
}
/**
* Method description
*
*
* @param path
*
* @return
*/
@VisibleForTesting
protected Iterator<URL> getModuleResources()
{
return CacheConfigurations.findModuleResources(
EhCacheConfigurationReader.class, MODULE_RESOURCES);
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param caches
*
* @return
*/
private Map<String, GuavaNamedCacheConfiguration> createNamedCacheMap(
List<GuavaNamedCacheConfiguration> caches)
{
Map<String, GuavaNamedCacheConfiguration> map = Maps.newLinkedHashMap();
for (GuavaNamedCacheConfiguration ncc : caches)
{
map.put(ncc.getName(), ncc);
}
return map;
}
/**
* Method description
*
*
* @return
*/
private GuavaCacheManagerConfiguration doRead()
{
URL defaultConfigUrl = getDefaultResource();
if (defaultConfigUrl == null)
{
throw new IllegalStateException(
"could not find default cache configuration");
}
GuavaCacheManagerConfiguration config = readConfiguration(defaultConfigUrl,
true);
Iterator<URL> it = getModuleResources();
while (it.hasNext())
{
GuavaCacheManagerConfiguration moduleConfig =
readConfiguration(it.next(), false);
if (moduleConfig != null)
{
config = merge(config, moduleConfig);
}
}
File manualFile = getManualFileResource();
if (manualFile.exists())
{
try
{
GuavaCacheManagerConfiguration manualConfig =
readConfiguration(manualFile.toURI().toURL(), false);
config = merge(config, manualConfig);
}
catch (MalformedURLException ex)
{
logger.error("malformed url", ex);
}
}
else
{
logger.warn("could not find manual configuration at {}", manualFile);
}
return config;
}
/**
* Method description
*
*
* @param config
* @param other
*
* @return
*/
private GuavaCacheManagerConfiguration merge(
GuavaCacheManagerConfiguration config, GuavaCacheManagerConfiguration other)
{
GuavaCacheConfiguration defaultCache = config.getDefaultCache();
Map<String, GuavaNamedCacheConfiguration> namedCaches =
createNamedCacheMap(config.getCaches());
if (other.getDefaultCache() != null)
{
defaultCache = other.getDefaultCache();
}
List<GuavaNamedCacheConfiguration> otherNamedCaches = other.getCaches();
for (GuavaNamedCacheConfiguration ncc : otherNamedCaches)
{
namedCaches.put(ncc.getName(), ncc);
}
return new GuavaCacheManagerConfiguration(defaultCache,
ImmutableList.copyOf(namedCaches.values()));
}
/**
* Method description
*
*
* @param url
* @param fail
*
* @return
*/
private GuavaCacheManagerConfiguration readConfiguration(URL url,
boolean fail)
{
GuavaCacheManagerConfiguration config = null;
try
{
config =
(GuavaCacheManagerConfiguration) context.createUnmarshaller().unmarshal(
url);
}
catch (JAXBException ex)
{
if (fail)
{
throw new CacheException("could not unmarshall cache configuration",
ex);
}
else
{
logger.warn("could not unmarshall cache configuration", ex);
}
}
return config;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private JAXBContext context;
}

View File

@@ -0,0 +1,153 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.cache;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Maps;
import com.google.inject.Singleton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//~--- JDK imports ------------------------------------------------------------
import java.io.IOException;
import java.util.Map;
/**
*
* @author Sebastian Sdorra
*/
@Singleton
public class GuavaCacheManager implements CacheManager
{
/**
* the logger for GuavaCacheManager
*/
private static final Logger logger =
LoggerFactory.getLogger(GuavaCacheManager.class);
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*/
public GuavaCacheManager()
{
this(GuavaCacheConfigurationReader.read());
}
/**
* Constructs ...
*
*
* @param config
*/
@VisibleForTesting
protected GuavaCacheManager(GuavaCacheManagerConfiguration config)
{
defaultConfiguration = config.getDefaultCache();
for (GuavaNamedCacheConfiguration ncc : config.getCaches())
{
cacheMap.put(ncc.getName(), new GuavaCache(ncc));
}
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @throws IOException
*/
@Override
public void close() throws IOException
{
logger.info("close guava cache manager");
for (Cache c : cacheMap.values())
{
c.clear();
}
cacheMap.clear();
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param key
* @param value
* @param name
* @param <K>
* @param <V>
*
* @return
*/
@Override
public synchronized <K, V> GuavaCache<K, V> getCache(Class<K> key,
Class<V> value, String name)
{
logger.trace("try to retrieve cache {}", name);
GuavaCache<K, V> cache = cacheMap.get(name);
if (cache == null)
{
logger.debug(
"cache {} does not exists, creating a new instance from default configuration: {}",
name, defaultConfiguration);
cache = new GuavaCache<K, V>(defaultConfiguration, name);
cacheMap.put(name, cache);
}
return cache;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private volatile Map<String, GuavaCache> cacheMap = Maps.newHashMap();
/** Field description */
private GuavaCacheConfiguration defaultConfiguration;
}

View File

@@ -0,0 +1,111 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.cache;
//~--- JDK imports ------------------------------------------------------------
import java.util.Collections;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
*
* @author Sebastian Sdorra
*/
@XmlRootElement(name = "caches")
@XmlAccessorType(XmlAccessType.FIELD)
public class GuavaCacheManagerConfiguration
{
/**
* Constructs ...
*
*/
public GuavaCacheManagerConfiguration() {}
/**
* Constructs ...
*
*
* @param defaultCache
* @param caches
*/
public GuavaCacheManagerConfiguration(GuavaCacheConfiguration defaultCache,
List<GuavaNamedCacheConfiguration> caches)
{
this.defaultCache = defaultCache;
this.caches = caches;
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
public List<GuavaNamedCacheConfiguration> getCaches()
{
if (caches == null)
{
caches = Collections.EMPTY_LIST;
}
return caches;
}
/**
* Method description
*
*
* @return
*/
public GuavaCacheConfiguration getDefaultCache()
{
return defaultCache;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
@XmlElement(name = "cache")
private List<GuavaNamedCacheConfiguration> caches;
/** Field description */
@XmlElement(name = "defaultCache")
private GuavaCacheConfiguration defaultCache;
}

View File

@@ -0,0 +1,156 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.cache;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.cache.CacheBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//~--- JDK imports ------------------------------------------------------------
import java.util.concurrent.TimeUnit;
/**
*
* @author Sebastian Sdorra
*/
public final class GuavaCaches
{
/**
* the logger for GuavaCaches
*/
private static final Logger logger =
LoggerFactory.getLogger(GuavaCaches.class);
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*/
private GuavaCaches() {}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param configuration
* @param name
*
* @return
*/
public static com.google.common.cache.Cache create(
GuavaCacheConfiguration configuration, String name)
{
CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder();
if (configuration.getConcurrencyLevel() != null)
{
builder.concurrencyLevel(configuration.getConcurrencyLevel());
}
if (configuration.getExpireAfterAccess() != null)
{
builder.expireAfterAccess(configuration.getExpireAfterAccess(),
TimeUnit.SECONDS);
}
if (configuration.getExpireAfterWrite() != null)
{
builder.expireAfterWrite(configuration.getExpireAfterWrite(),
TimeUnit.SECONDS);
}
if (configuration.getInitialCapacity() != null)
{
builder.initialCapacity(configuration.getInitialCapacity());
}
if (configuration.getMaximumSize() != null)
{
builder.maximumSize(configuration.getMaximumSize());
}
if (configuration.getMaximumWeight() != null)
{
builder.maximumWeight(configuration.getMaximumWeight());
}
if (isEnabled(configuration.getRecordStats()))
{
builder.recordStats();
}
if (isEnabled(configuration.getSoftValues()))
{
builder.softValues();
}
if (isEnabled(configuration.getWeakKeys()))
{
builder.weakKeys();
}
if (isEnabled(configuration.getWeakValues()))
{
builder.weakKeys();
}
if (logger.isTraceEnabled())
{
logger.trace("create new cache {} from builder: {}", name, builder);
}
return builder.build();
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param v
*
* @return
*/
private static boolean isEnabled(Boolean v)
{
return (v != null) && v;
}
}

View File

@@ -0,0 +1,71 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.cache;
//~--- JDK imports ------------------------------------------------------------
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
/**
*
* @author Sebastian Sdorra
*/
@XmlRootElement(name = "cache")
@XmlAccessorType(XmlAccessType.FIELD)
public class GuavaNamedCacheConfiguration extends GuavaCacheConfiguration
{
/** Field description */
private static final long serialVersionUID = -624795324874828475L;
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
public String getName()
{
return name;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
@XmlAttribute
private String name;
}

View File

@@ -37,6 +37,7 @@ package sonia.scm.search;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
@@ -139,7 +140,11 @@ public class SearchHandler<T>
Collections2.transform(users, function);
result.setSuccess(true);
result.setResults(resultCollection);
// create a copy of the result collection to reduce memory
// use ArrayList instead of ImmutableList for copy,
// because the list must be mutable for decorators
result.setResults(Lists.newArrayList(resultCollection));
cache.put(queryString, result);
}
}

View File

@@ -40,7 +40,9 @@
Purpose of the document follows.
-->
<ehcache xmlns="http://ehcache.org/ehcache.xsd">
<ehcache xmlns="http://ehcache.org/ehcache.xsd"
updateCheck="false"
maxBytesLocalDisk="512M">
<!--
@@ -88,18 +90,23 @@
-->
<defaultCache
maxElementsInMemory="20000"
maxEntriesLocalHeap="100"
maxEntriesLocalDisk="10000"
eternal="false"
overflowToDisk="false"
overflowToDisk="true"
timeToIdleSeconds="1200"
timeToLiveSeconds="2400"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="2400"
diskExpiryThreadIntervalSeconds="120"
/>
<!--
Authentication cache
average: 1K
-->
<cache
name="sonia.cache.auth"
maxElementsInMemory="200000"
maxEntriesLocalHeap="1000"
eternal="false"
overflowToDisk="false"
timeToIdleSeconds="30"
@@ -107,38 +114,135 @@
diskPersistent="false"
/>
<!--
Authorization cache
average: 3K
-->
<cache
name="sonia.cache.authorizing"
maxEntriesLocalHeap="1000"
eternal="false"
overflowToDisk="false"
timeToIdleSeconds="1200"
timeToLiveSeconds="2400"
diskPersistent="false"
/>
<!--
PluginCenter cache
average: 30K
-->
<cache
name="sonia.cache.plugins"
maxElementsInMemory="10"
maxEntriesLocalHeap="5"
eternal="false"
overflowToDisk="false"
timeToLiveSeconds="3600"
diskPersistent="false"
/>
<!--
Search cache for users
average: 0.5K
-->
<cache
name="sonia.cache.search.users"
maxElementsInMemory="10000"
maxEntriesLocalHeap="10000"
eternal="false"
overflowToDisk="false"
timeToLiveSeconds="5400"
diskPersistent="false"
/>
<!--
Search cache for groups
average: 0.5K
-->
<cache
name="sonia.cache.search.groups"
maxElementsInMemory="1000"
maxEntriesLocalHeap="1000"
eternal="false"
overflowToDisk="false"
timeToLiveSeconds="5400"
diskPersistent="false"
/>
<!-- old repository api -->
<!-- new repository api -->
<!--
Changeset cache
average: 25K
-->
<cache
name="sonia.cache.cmd.log"
maxEntriesLocalHeap="200"
maxEntriesLocalDisk="10000"
eternal="true"
overflowToDisk="true"
diskPersistent="false"
copyOnRead="true"
copyOnWrite="true"
/>
<!--
FileObject cache
average: 1.5K
-->
<cache
name="sonia.cache.cmd.browse"
maxEntriesLocalHeap="3000"
maxEntriesLocalDisk="20000"
eternal="true"
overflowToDisk="true"
diskPersistent="false"
copyOnRead="true"
copyOnWrite="true"
/>
<!--
BlameResult cache
average: 15K
-->
<cache
name="sonia.cache.cmd.blame"
maxEntriesLocalHeap="1000"
maxEntriesLocalDisk="10000"
eternal="true"
overflowToDisk="true"
diskPersistent="false"
copyOnRead="true"
copyOnWrite="true"
/>
<!--
Tag cache
average: 5K
-->
<cache
name="sonia.cache.cmd.tags"
maxEntriesLocalHeap="500"
eternal="true"
overflowToDisk="false"
diskPersistent="false"
/>
<!--
Branch cache
average: 2.5K
-->
<cache
name="sonia.cache.cmd.branches"
maxEntriesLocalHeap="1000"
eternal="true"
overflowToDisk="false"
diskPersistent="false"
/>
<!-- deprecated old repository api -->
<cache
name="sonia.cache.repository.changesets"
maxElementsInMemory="20000"
maxEntriesLocalHeap="200"
eternal="false"
overflowToDisk="false"
timeToLiveSeconds="86400"
@@ -147,7 +251,7 @@
<cache
name="sonia.cache.repository.browser"
maxElementsInMemory="10000"
maxEntriesLocalHeap="200"
eternal="false"
overflowToDisk="false"
timeToLiveSeconds="86400"
@@ -156,59 +260,11 @@
<cache
name="sonia.cache.repository.blame"
maxElementsInMemory="1000"
maxEntriesLocalHeap="100"
eternal="false"
overflowToDisk="false"
timeToLiveSeconds="86400"
diskPersistent="false"
/>
<!-- new repository api -->
<cache
name="sonia.cache.cmd.log"
maxElementsInMemory="20000"
eternal="true"
overflowToDisk="false"
diskPersistent="false"
copyOnRead="true"
copyOnWrite="true"
/>
<cache
name="sonia.cache.cmd.browse"
maxElementsInMemory="10000"
eternal="true"
overflowToDisk="false"
diskPersistent="false"
copyOnRead="true"
copyOnWrite="true"
/>
<cache
name="sonia.cache.cmd.blame"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
diskPersistent="false"
copyOnRead="true"
copyOnWrite="true"
/>
<cache
name="sonia.cache.cmd.tags"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
diskPersistent="false"
/>
<cache
name="sonia.cache.cmd.branches"
maxElementsInMemory="1000"
eternal="true"
overflowToDisk="false"
diskPersistent="false"
/>
</ehcache>

View File

@@ -0,0 +1,145 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--*
Copyright (c) 2010, Sebastian Sdorra
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of SCM-Manager; nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
http://bitbucket.org/sdorra/scm-manager
-->
<caches>
<defaultCache
maximumSize="200"
expireAfterAccess="1200"
expireAfterWrite="2400"
/>
<!--
Authentication cache
average: 1K
-->
<cache
name="sonia.cache.auth"
maximumSize="1000"
expireAfterAccess="30"
expireAfterWrite="60"
/>
<!--
Authorization cache
average: 3K
-->
<cache
name="sonia.cache.authorizing"
maximumSize="1000"
expireAfterAccess="1200"
expireAfterWrite="2400"
/>
<!--
PluginCenter cache
average: 30K
-->
<cache
name="sonia.cache.plugins"
maximumSize="5"
expireAfterWrite="3600"
/>
<!--
Search cache for users
average: 0.5K
-->
<cache
name="sonia.cache.search.users"
maximumSize="10000"
expireAfterWrite="5400"
/>
<!--
Search cache for groups
average: 0.5K
-->
<cache
name="sonia.cache.search.groups"
maximumSize="1000"
expireAfterWrite="5400"
/>
<!-- new repository api -->
<!--
Changeset cache
average: 25K
-->
<cache
name="sonia.cache.cmd.log"
maximumSize="500"
copyStrategy="read-write"
/>
<!--
FileObject cache
average: 1.5K
-->
<cache
name="sonia.cache.cmd.browse"
maximumSize="3000"
copyStrategy="read-write"
/>
<!--
BlameResult cache
average: 15K
-->
<cache
name="sonia.cache.cmd.blame"
maximumSize="1000"
copyStrategy="read-write"
/>
<!--
Tag cache
average: 5K
-->
<cache
name="sonia.cache.cmd.tags"
maximumSize="500"
/>
<!--
Branch cache
average: 2.5K
-->
<cache
name="sonia.cache.cmd.branches"
maximumSize="500"
/>
</caches>

View File

@@ -77,6 +77,11 @@
<logger name="com.aragost.javahg" level="DEBUG" />
-->
<!-- ehcache -->
<!--
<logger name="net.sf.ehcache" level="DEBUG" />
-->
<root level="WARN">
<appender-ref ref="STDOUT" />
</root>

View File

@@ -99,6 +99,11 @@
<logger name="com.aragost.javahg" level="DEBUG" />
-->
<!-- ehcache -->
<!--
<logger name="net.sf.ehcache" level="DEBUG" />
-->
<root level="WARN">
<appender-ref ref="FILE" />
<appender-ref ref="STDOUT" />

View File

@@ -0,0 +1,224 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.cache;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.collect.Sets;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
//~--- JDK imports ------------------------------------------------------------
import java.io.IOException;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
*
* @author Sebastian Sdorra
*
* @param <C>
*/
public abstract class CacheManagerTestBase<C extends Cache>
{
/**
* Method description
*
*
* @return
*/
protected abstract CacheManager createCacheManager();
/**
* Method description
*
*
* @throws IOException
*/
@After
public void tearDown() throws IOException
{
cacheManager.close();
}
/**
* Method description
*
*/
@Test
public void testSameReference()
{
Cache<String, String> c1 = cacheManager.getCache(String.class,
String.class, "test-1");
Cache<String, String> c2 = cacheManager.getCache(String.class,
String.class, "test-1");
assertIsSame(c1, c2);
}
/**
* Method description
*
*
* @throws ExecutionException
* @throws InterruptedException
*/
@Test
public void testSameReferenceMultiThreaded()
throws InterruptedException, ExecutionException
{
ExecutorService executor = Executors.newFixedThreadPool(2);
Set<Future<Cache>> caches = Sets.newHashSet();
for (int i = 0; i < 20; i++)
{
//J-
caches.add(
executor.submit(new AcquireCacheCallable(cacheManager, "test-2"))
);
//J+
}
executor.shutdown();
Cache c = null;
for (Future<Cache> f : caches)
{
Cache nc = f.get();
if (c != null)
{
assertIsSame(c, nc);
}
c = nc;
}
}
//~--- set methods ----------------------------------------------------------
/**
* Method description
*
*/
@Before
public void setUp()
{
cacheManager = createCacheManager();
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param c1
* @param c2
*/
protected void assertIsSame(Cache<String, String> c1,
Cache<String, String> c2)
{
assertSame(c1, c2);
}
//~--- inner classes --------------------------------------------------------
/**
* Class description
*
*
* @version Enter version here..., 13/03/25
* @author Enter your name here...
*/
private static class AcquireCacheCallable implements Callable<Cache>
{
/**
* Constructs ...
*
*
* @param cacheManager
* @param name
*/
public AcquireCacheCallable(CacheManager cacheManager, String name)
{
this.cacheManager = cacheManager;
this.name = name;
}
//~--- methods ------------------------------------------------------------
/**
* Method description
*
*
* @return
*
* @throws Exception
*/
@Override
public Cache call() throws Exception
{
return cacheManager.getCache(String.class, String.class, name);
}
//~--- fields -------------------------------------------------------------
/** Field description */
private CacheManager cacheManager;
/** Field description */
private String name;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private CacheManager cacheManager;
}

View File

@@ -0,0 +1,165 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.cache;
//~--- non-JDK imports --------------------------------------------------------
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import sonia.scm.Filter;
import sonia.scm.util.IOUtil;
import static org.junit.Assert.*;
/**
*
* @author Sebastian Sdorra
*/
public abstract class CacheTestBase
{
/**
* Method description
*
*
* @return
*/
protected abstract CacheManager createCacheManager();
/**
* Method description
*
*/
@After
public void after()
{
IOUtil.close(cm);
}
/**
* Method description
*
*/
@Before
public void before()
{
cm = createCacheManager();
cache = cm.getCache(String.class, String.class, "test");
}
/**
* Method description
*
*/
@Test
public void testClear()
{
cache.put("test", "test123");
cache.put("test-1", "test123");
cache.clear();
assertNull(cache.get("test"));
assertNull(cache.get("test-1"));
}
/**
* Method description
*
*/
@Test
public void testContains()
{
cache.put("test", "test123");
cache.put("test-1", "test123");
assertTrue(cache.contains("test"));
assertTrue(cache.contains("test-1"));
assertFalse(cache.contains("test-2"));
}
/**
* Method description
*
*/
@Test
public void testPutAndGet()
{
cache.put("test", "test123");
assertEquals("test123", cache.get("test"));
}
/**
* Method description
*
*/
@Test
public void testRemove()
{
cache.put("test", "test123");
assertEquals("test123", cache.get("test"));
cache.remove("test");
assertNull(cache.get("test"));
}
/**
* Method description
*
*/
@Test
public void testRemoveAll()
{
cache.put("test-1", "test123");
cache.put("test-2", "test123");
cache.put("a-1", "test123");
cache.put("a-2", "test123");
cache.removeAll(new Filter<String>()
{
@Override
public boolean accept(String item)
{
return item.startsWith("test");
}
});
assertNull(cache.get("test-1"));
assertNull(cache.get("test-2"));
assertNotNull(cache.get("a-1"));
assertNotNull(cache.get("a-2"));
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private Cache<String, String> cache;
/** Field description */
private CacheManager cm;
}

View File

@@ -0,0 +1,77 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.cache;
//~--- JDK imports ------------------------------------------------------------
import java.util.Collections;
/**
*
* @author Sebastian Sdorra
*/
public final class CacheTestUtil
{
/**
* Constructs ...
*
*/
private CacheTestUtil() {}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @return
*/
public static EhCacheManager createDefaultEhCacheManager()
{
return new EhCacheManager(net.sf.ehcache.CacheManager.create());
}
/**
* Method description
*
*
* @return
*/
public static GuavaCacheManager createDefaultGuavaCacheManager()
{
GuavaCacheConfiguration config = new GuavaCacheConfiguration();
return new GuavaCacheManager(new GuavaCacheManagerConfiguration(config,
Collections.EMPTY_LIST));
}
}

View File

@@ -0,0 +1,84 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.cache;
//~--- non-JDK imports --------------------------------------------------------
import org.junit.Assert;
/**
*
* @author Sebastian Sdorra
*/
public class EhCacheManagerTest extends CacheManagerTestBase
{
/**
* Method description
*
*
* @param c1
* @param c2
*/
@Override
protected void assertIsSame(Cache c1, Cache c2)
{
Assert.assertSame(getCacheImplementation(c1), getCacheImplementation(c1));
}
/**
* Method description
*
*
* @return
*/
@Override
protected CacheManager createCacheManager()
{
return CacheTestUtil.createDefaultEhCacheManager();
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param c1
*
* @return
*/
private net.sf.ehcache.Cache getCacheImplementation(Cache c1)
{
return ((EhCache) c1).getCacheImplementation();
}
}

View File

@@ -33,127 +33,22 @@
package sonia.scm.cache;
//~--- non-JDK imports --------------------------------------------------------
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import sonia.scm.Filter;
import sonia.scm.util.IOUtil;
import static org.junit.Assert.*;
/**
*
* @author Sebastian Sdorra
*/
public class EhCacheTest
public class EhCacheTest extends CacheTestBase
{
/**
* Method description
*
*/
@After
public void after()
{
IOUtil.close(cm);
}
/**
* Method description
*
* @return
*/
@Before
public void before()
{
cm = new EhCacheManager(net.sf.ehcache.CacheManager.create());
cache = cm.getCache(String.class, String.class, "test");
}
/**
* Method description
*
*/
@Test
public void testClear()
{
cache.put("test", "test123");
cache.put("test-1", "test123");
cache.clear();
assertNull(cache.get("test"));
assertNull(cache.get("test-1"));
}
/**
* Method description
*
*/
@Test
public void testContains()
{
cache.put("test", "test123");
cache.put("test-1", "test123");
assertTrue(cache.contains("test"));
assertTrue(cache.contains("test-1"));
assertFalse(cache.contains("test-2"));
}
/**
* Method description
*
*/
@Test
public void testPutAndGet()
{
cache.put("test", "test123");
assertEquals("test123", cache.get("test"));
}
/**
* Method description
*
*/
@Test
public void testRemove()
{
cache.put("test", "test123");
assertEquals("test123", cache.get("test"));
cache.remove("test");
assertNull(cache.get("test"));
}
/**
* Method description
*
*/
@Test
public void testRemoveAll()
{
cache.put("test-1", "test123");
cache.put("test-2", "test123");
cache.put("a-1", "test123");
cache.put("a-2", "test123");
cache.removeAll(new Filter<String>()
{
@Override
public boolean accept(String item)
protected CacheManager createCacheManager()
{
return item.startsWith("test");
return CacheTestUtil.createDefaultEhCacheManager();
}
});
assertNull(cache.get("test-1"));
assertNull(cache.get("test-2"));
assertNotNull(cache.get("a-1"));
assertNotNull(cache.get("a-2"));
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private Cache<String, String> cache;
/** Field description */
private CacheManager cm;
}

View File

@@ -0,0 +1,464 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.cache;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.base.Function;
import com.google.common.collect.Iterators;
import com.google.common.io.Closeables;
import com.google.common.io.Files;
import com.google.common.io.Resources;
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.config.Configuration;
import net.sf.ehcache.config.ConfigurationFactory;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
//~--- JDK imports ------------------------------------------------------------
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Iterator;
/**
*
* @author Sebastian Sdorra
*/
public class EhConfigurationReaderTest
{
/**
* Method description
*
*/
@Test
public void testDefaultConfiguration()
{
EhConfigurationTestReader reader =
new EhConfigurationTestReader("cache.001.xml");
Configuration c = createConfiguration(reader);
checkDefaultConfiguration(c);
checkCacheConfiguration(c, "sonia.test.cache.001", 1000l, 30l, 60l);
}
/**
* Method description
*
*/
@Test
public void testGlobalAttributes()
{
EhConfigurationTestReader reader =
new EhConfigurationTestReader("cache.006.xml");
Configuration c = createConfiguration(reader);
assertFalse(c.getUpdateCheck());
assertEquals("512M", c.getMaxBytesLocalDiskAsString());
}
/**
* Method description
*
*/
@Test
public void testMergeAndOverride()
{
//J-
EhConfigurationTestReader reader = new EhConfigurationTestReader(
"cache.001.xml",
Iterators.forArray("cache.002.xml", "cache.003.xml"),
"cache.004.xml"
);
//J+
Configuration c = createConfiguration(reader);
// cache sonia.test.cache.001 override by cache.004.xml
checkCacheConfiguration(c, "sonia.test.cache.001", 6l, 2l, 8l);
checkCacheConfiguration(c, "sonia.test.cache.002", 2000l, 60l, 120l);
checkCacheConfiguration(c, "sonia.test.cache.003", 3000l, 120l, 2400l);
}
/**
* Method description
*
*/
@Test
public void testMergeWithManualConfiguration()
{
EhConfigurationTestReader reader =
new EhConfigurationTestReader("cache.001.xml", null, "cache.002.xml");
Configuration c = createConfiguration(reader);
checkDefaultConfiguration(c);
checkCacheConfiguration(c, "sonia.test.cache.001", 1000l, 30l, 60l);
checkCacheConfiguration(c, "sonia.test.cache.002", 2000l, 60l, 120l);
}
/**
* Method description
*
*/
@Test
public void testMergeWithModuleConfigurations()
{
EhConfigurationTestReader reader =
new EhConfigurationTestReader("cache.001.xml",
Iterators.forArray("cache.002.xml", "cache.003.xml"));
Configuration c = createConfiguration(reader);
checkDefaultConfiguration(c);
checkCacheConfiguration(c, "sonia.test.cache.001", 1000l, 30l, 60l);
checkCacheConfiguration(c, "sonia.test.cache.002", 2000l, 60l, 120l);
checkCacheConfiguration(c, "sonia.test.cache.003", 3000l, 120l, 2400l);
}
/**
* Method description
*
*/
@Test(expected = IllegalStateException.class)
public void testMissingDefaultConfiguration()
{
EhConfigurationTestReader reader = new EhConfigurationTestReader();
reader.read();
}
/**
* Method description
*
*/
@Test
public void testOverrideDefaultConfiguration()
{
//J-
EhConfigurationTestReader reader = new EhConfigurationTestReader(
"cache.001.xml",
Iterators.forArray("cache.005.xml")
);
//J+
Configuration c = createConfiguration(reader);
checkDefaultConfiguration(c, 170l, 18900l);
}
/**
* Method description
*
*/
@Test
public void testOverrideGlobalAttributes()
{
EhConfigurationTestReader reader =
new EhConfigurationTestReader("cache.006.xml", null, "cache.007.xml");
Configuration c = createConfiguration(reader);
assertTrue(c.getUpdateCheck());
assertEquals("1G", c.getMaxBytesLocalDiskAsString());
}
/**
* Method description
*
*
* @param c
* @param name
* @param maxEntriesLocalHeap
* @param timeToIdleSeconds
* @param timeToLiveSeconds
*/
private void checkCacheConfiguration(Configuration c, String name,
long maxEntriesLocalHeap, long timeToIdleSeconds, long timeToLiveSeconds)
{
CacheConfiguration cc = c.getCacheConfigurations().get(name);
assertNotNull(cc);
assertEquals(maxEntriesLocalHeap, cc.getMaxEntriesLocalHeap());
assertEquals(timeToIdleSeconds, cc.getTimeToIdleSeconds());
assertEquals(timeToLiveSeconds, cc.getTimeToLiveSeconds());
}
/**
* Method description
*
*
* @param c
*/
private void checkDefaultConfiguration(Configuration c)
{
checkDefaultConfiguration(c, 100l, 10000l);
}
/**
* Method description
*
*
* @param c
* @param maxEntriesLocalHeap
* @param maxEntriesLocalDisk
*/
private void checkDefaultConfiguration(Configuration c,
long maxEntriesLocalHeap, long maxEntriesLocalDisk)
{
CacheConfiguration dcc = c.getDefaultCacheConfiguration();
assertNotNull(dcc);
assertEquals(maxEntriesLocalHeap, dcc.getMaxEntriesLocalHeap());
assertEquals(maxEntriesLocalDisk, dcc.getMaxEntriesLocalDisk());
}
/**
* Method description
*
*
* @param reader
*
* @return
*/
private Configuration createConfiguration(EhCacheConfigurationReader reader)
{
Configuration config = null;
InputStream content = null;
try
{
content = reader.read();
config = ConfigurationFactory.parseConfiguration(content);
}
finally
{
Closeables.closeQuietly(content);
}
assertNotNull(config);
return config;
}
//~--- inner classes --------------------------------------------------------
/**
* Class description
*
*
* @version Enter version here..., 13/03/19
* @author Enter your name here...
*/
private class EhConfigurationTestReader extends EhCacheConfigurationReader
{
/**
* Constructs ...
*
*/
public EhConfigurationTestReader() {}
/**
* Constructs ...
*
*
* @param defaultConfiguration
*/
public EhConfigurationTestReader(String defaultConfiguration)
{
this.defaultConfiguration = defaultConfiguration;
}
/**
* Constructs ...
*
*
* @param defaultConfiguration
* @param moduleConfigurations
*/
public EhConfigurationTestReader(String defaultConfiguration,
Iterator<String> moduleConfigurations)
{
this.defaultConfiguration = defaultConfiguration;
this.moduleConfigurations = moduleConfigurations;
}
/**
* Constructs ...
*
*
* @param defaultConfiguration
* @param moduleConfigurations
* @param manualConfiguration
*/
public EhConfigurationTestReader(String defaultConfiguration,
Iterator<String> moduleConfigurations, String manualConfiguration)
{
this.defaultConfiguration = defaultConfiguration;
this.moduleConfigurations = moduleConfigurations;
this.manualConfiguration = manualConfiguration;
}
//~--- get methods --------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@Override
public URL getDefaultResource()
{
URL url = null;
if (defaultConfiguration != null)
{
url = getResource(defaultConfiguration);
}
return url;
}
/**
* Method description
*
*
* @return
*/
@Override
public Iterator<URL> getModuleResources()
{
Iterator<URL> urlIterator;
if (moduleConfigurations == null)
{
urlIterator = Iterators.emptyIterator();
}
else
{
urlIterator = Iterators.transform(moduleConfigurations,
new Function<String, URL>()
{
@Override
public URL apply(String resource)
{
return getResource(resource);
}
});
}
return urlIterator;
}
/**
* Method description
*
*
* @return
*/
@Override
protected File getManualFileResource()
{
File file;
if (manualConfiguration == null)
{
file = mock(File.class);
when(file.exists()).thenReturn(Boolean.FALSE);
}
else
{
try
{
file = tempFolder.newFile();
URL manual = getResource(manualConfiguration);
Files.copy(Resources.newInputStreamSupplier(manual), file);
}
catch (IOException ex)
{
throw new RuntimeException("could not create manual config file", ex);
}
}
return file;
}
/**
* Method description
*
*
* @param name
*
* @return
*/
private URL getResource(String name)
{
return Resources.getResource("sonia/scm/cache/".concat(name));
}
//~--- fields -------------------------------------------------------------
/** Field description */
private String defaultConfiguration;
/** Field description */
private String manualConfiguration;
/** Field description */
private Iterator<String> moduleConfigurations;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
@Rule
public TemporaryFolder tempFolder = new TemporaryFolder();
}

View File

@@ -0,0 +1,52 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.cache;
/**
*
* @author Sebastian Sdorra
*/
public class GuavaCacheManagerTest extends CacheManagerTestBase
{
/**
* Method description
*
*
* @return
*/
@Override
protected CacheManager createCacheManager()
{
return CacheTestUtil.createDefaultGuavaCacheManager();
}
}

View File

@@ -0,0 +1,54 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.cache;
//~--- JDK imports ------------------------------------------------------------
/**
*
* @author Sebastian Sdorra
*/
public class GuavaCacheTest extends CacheTestBase
{
/**
* Method description
*
*
* @return
*/
@Override
protected CacheManager createCacheManager()
{
return CacheTestUtil.createDefaultGuavaCacheManager();
}
}

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--*
Copyright (c) 2010, Sebastian Sdorra
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of SCM-Manager; nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
http://bitbucket.org/sdorra/scm-manager
-->
<ehcache xmlns="http://ehcache.org/ehcache.xsd">
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxEntriesLocalHeap="100"
maxEntriesLocalDisk="10000"
/>
<cache
name="sonia.test.cache.001"
maxEntriesLocalHeap="1000"
timeToIdleSeconds="30"
timeToLiveSeconds="60"
/>
</ehcache>

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--*
Copyright (c) 2010, Sebastian Sdorra
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of SCM-Manager; nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
http://bitbucket.org/sdorra/scm-manager
-->
<ehcache xmlns="http://ehcache.org/ehcache.xsd">
<cache
name="sonia.test.cache.002"
maxEntriesLocalHeap="2000"
timeToIdleSeconds="60"
timeToLiveSeconds="120"
/>
</ehcache>

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--*
Copyright (c) 2010, Sebastian Sdorra
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of SCM-Manager; nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
http://bitbucket.org/sdorra/scm-manager
-->
<ehcache xmlns="http://ehcache.org/ehcache.xsd">
<cache
name="sonia.test.cache.003"
maxEntriesLocalHeap="3000"
timeToIdleSeconds="120"
timeToLiveSeconds="2400"
/>
</ehcache>

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--*
Copyright (c) 2010, Sebastian Sdorra
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of SCM-Manager; nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
http://bitbucket.org/sdorra/scm-manager
-->
<ehcache xmlns="http://ehcache.org/ehcache.xsd">
<cache
name="sonia.test.cache.001"
maxEntriesLocalHeap="6"
timeToIdleSeconds="2"
timeToLiveSeconds="8"
/>
</ehcache>

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--*
Copyright (c) 2010, Sebastian Sdorra
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of SCM-Manager; nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
http://bitbucket.org/sdorra/scm-manager
-->
<ehcache xmlns="http://ehcache.org/ehcache.xsd">
<defaultCache
maxEntriesLocalHeap="170"
maxEntriesLocalDisk="18900"
/>
</ehcache>

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--*
Copyright (c) 2010, Sebastian Sdorra
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of SCM-Manager; nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
http://bitbucket.org/sdorra/scm-manager
-->
<ehcache xmlns="http://ehcache.org/ehcache.xsd"
updateCheck="false"
maxBytesLocalDisk="512M">
</ehcache>

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--*
Copyright (c) 2010, Sebastian Sdorra
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of SCM-Manager; nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
http://bitbucket.org/sdorra/scm-manager
-->
<ehcache xmlns="http://ehcache.org/ehcache.xsd"
updateCheck="true"
maxBytesLocalDisk="1G">
</ehcache>

View File

@@ -0,0 +1,86 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
// see https://bitbucket.org/sdorra/scm-manager/issue/345/ehcache-eating-up-all-memory
def humanReadable(def bytes) {
if (bytes < 1024) return bytes + " B";
int exp = (int) (Math.log(bytes) / Math.log(1024));
String pre = "KMGTPE".charAt(exp-1);
return String.format("%.1f %sB", bytes / Math.pow(1024, exp), pre);
}
def sizeOf(Serializable object){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
oos.close();
return baos.size();
}
Runtime runtime = Runtime.getRuntime();
def maxMemory = runtime.maxMemory();
def allocatedMemory = runtime.totalMemory();
def freeMemory = runtime.freeMemory();
println "memory:"
println " - max : " + humanReadable(maxMemory);
println " - allocated : " + humanReadable(allocatedMemory);
println " - free : " + humanReadable(freeMemory);
println "";
println "";
def cacheManager = injector.getInstance(sonia.scm.cache.CacheManager.class).cacheManager;
def totalCMax = 0;
def cacheNames = cacheManager.getCacheNames();
for ( def cacheName : cacheNames ){
def cache = cacheManager.getCache(cacheName);
def totalMemory = cache.calculateInMemorySize();
def average = cache.getSize() > 0 ? Math.round( totalMemory / cache.getSize() ) : 0;
def max = cache.getCacheConfiguration().getMaxEntriesLocalHeap();
def maxSize = average * max;
totalCMax += maxSize;
println cache.name + ":";
println " - size : " + cache.getSize();
println " - maxsize : " + max;
println " - average : " + humanReadable( average );
println " - current : " + humanReadable( totalMemory );
println " - cmax : " + humanReadable( maxSize );
}
println "";
println "";
println "Total CMax: " + humanReadable(totalCMax);