Skip to content

Commit

Permalink
[feature] Adds in memory cache for query results
Browse files Browse the repository at this point in the history
- Use in memory caching for resuls smaller 4 MB adding new
  CachedContentFile and companion test case
- Extended XmlRpcTest to improve coverage of RpcConnection
- Added new QueryResultCacheTest

Signed-off-by: Patrick Reinhart <patrick@reini.net>
  • Loading branch information
reinhapa committed Jan 15, 2024
1 parent c5c1a0d commit c23ad3f
Show file tree
Hide file tree
Showing 13 changed files with 948 additions and 352 deletions.
5 changes: 5 additions & 0 deletions exist-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,11 @@
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;

/**
Expand Down Expand Up @@ -84,7 +83,7 @@ public int read() throws IOException {
public int read(byte[] b, int off, int len) throws IOException {
boolean success = false;
int read = 0;
while (!success) {
while (!success && len > 0) {
long positionBefore = POSITION_UPDATER.get(this);
read = this.memoryContents.read(b, positionBefore, off, len);
if (read < 1) {
Expand Down Expand Up @@ -115,13 +114,4 @@ public long skip(long n) throws IOException {
}
return skipped;
}

// Java 9 method, has to compile under Java 1.7 so no @Override
public long transferTo(OutputStream out) throws IOException {
long positionBefore = POSITION_UPDATER.get(this);
long written = this.memoryContents.transferTo(out, positionBefore);
POSITION_UPDATER.set(this, this.memoryContents.size());
return written;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ public final class VirtualTempPath implements ContentFile {
@GuardedBy("lock")
private Path contentFile;

public VirtualTempPath(TemporaryFileManager tempFileManager) {
this(DEFAULT_IN_MEMORY_SIZE, tempFileManager);
}

public VirtualTempPath(int inMemorySize, TemporaryFileManager tempFileManager) {
this.inMemorySize = inMemorySize;
this.lock = new StampedLock();
Expand Down Expand Up @@ -96,6 +100,7 @@ public OutputStream newOutputStream() throws IOException {
}
}

@Override
public InputStream newInputStream() throws IOException {
long stamp = lock.readLock();
try {
Expand Down Expand Up @@ -128,6 +133,7 @@ public void close() {
}
}

@Override
public long size() {
long stamp = lock.readLock();
try {
Expand All @@ -140,6 +146,7 @@ public long size() {
}
}

@Override
public byte[] getBytes() {
long stamp = lock.readLock();
try {
Expand Down
48 changes: 48 additions & 0 deletions exist-core/src/main/java/org/exist/xmlrpc/CachedContentFile.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
* info@exist-db.org
* http://www.exist-db.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.exist.xmlrpc;

import org.exist.util.io.ContentFile;

/**
* @author <a href="mailto:patrick@reini.net">Patrick Reinhart</a>
*/
public final class CachedContentFile extends AbstractCachedResult {
private final ContentFile result;

public CachedContentFile(final ContentFile result) {
super(0);
this.result = result;
}

@Override
public ContentFile getResult() {
return result;
}

@Override
protected void doClose() {
if (result != null) {
result.close();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ public SerializedResult getSerializedResult(final int cacheId) {
return (acr != null && acr instanceof SerializedResult) ? (SerializedResult) acr : null;
}

public CachedContentFile getCachedContentFile(final int cacheId) {
final AbstractCachedResult acr = get(cacheId);
return (acr != null && acr instanceof CachedContentFile) ? (CachedContentFile) acr : null;
}

public void remove(final int cacheId) {
if (cacheId < 0 || cacheId >= cacheIdCounter.get()) {
return; // out of scope
Expand Down
16 changes: 9 additions & 7 deletions exist-core/src/main/java/org/exist/xmlrpc/RpcAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public interface RpcAPI {
/**
* Retrieve document by name. XML content is indented if prettyPrint is set
* to &gt;=0. Use supplied encoding for output.
*
* <p>
* This method is provided to retrieve a document with encodings other than
* UTF-8. Since the data is handled as binary data, character encodings are
* preserved. byte[]-values are automatically BASE64-encoded by the XMLRPC
Expand All @@ -132,7 +132,7 @@ byte[] getDocument(String name, String encoding, int prettyPrint)
* Retrieve document by name. XML content is indented if prettyPrint is set
* to &gt;=0. Use supplied encoding for output and apply the specified
* stylesheet.
*
* <p>
* This method is provided to retrieve a document with encodings other than
* UTF-8. Since the data is handled as binary data, character encodings are
* preserved. byte[]-values are automatically BASE64-encoded by the XMLRPC
Expand All @@ -152,7 +152,7 @@ byte[] getDocument(String name, String encoding, int prettyPrint, String stylesh
/**
* Retrieve document by name. All optional output parameters are passed as
* key/value pairs int the <code>parameters</code>.
*
* <p>
* Valid keys may either be taken from
* {@link javax.xml.transform.OutputKeys} or
* {@link org.exist.storage.serializers.EXistOutputKeys}. For example, the
Expand Down Expand Up @@ -247,10 +247,10 @@ List<String> getCollectionListing(final String collection)
List<String> getDocumentListing(String collection)
throws EXistException, PermissionDeniedException, URISyntaxException;

Map<String, List> listDocumentPermissions(String name)
Map<String, List<Object>> listDocumentPermissions(String name)
throws EXistException, PermissionDeniedException, URISyntaxException;

Map<XmldbURI, List> listCollectionPermissions(String name)
Map<String, List<Object>> listCollectionPermissions(String name)
throws EXistException, PermissionDeniedException, URISyntaxException;

/**
Expand Down Expand Up @@ -497,6 +497,7 @@ byte[] query(
* @throws PermissionDeniedException If the current user is not allowed to perform this action
* @deprecated use List query() or int executeQuery() instead
*/
@Deprecated
Map<String, Object> querySummary(String xquery)
throws EXistException, PermissionDeniedException;

Expand Down Expand Up @@ -612,7 +613,7 @@ String uploadCompressed(String file, byte[] data, int length)

/**
* Parse a file previously uploaded with upload.
*
* <p>
* The temporary file will be removed.
*
* @param localFile temporary file name
Expand Down Expand Up @@ -749,6 +750,7 @@ Map<String, Object> execute(String path, Map<String, Object> parameters)
*
* @deprecated Use {@link #executeT(String, Map)} instead.
*/
@Deprecated
Map<String, Object> executeT(String path, Map<String, Object> parameters)
throws EXistException, PermissionDeniedException;

Expand Down Expand Up @@ -926,7 +928,7 @@ String hasUserLock(String path)

List<String> getGroups() throws EXistException, PermissionDeniedException;

List<List> getIndexedElements(String collectionName, boolean inclusive)
List<List<Object>> getIndexedElements(String collectionName, boolean inclusive)
throws EXistException, PermissionDeniedException, URISyntaxException;

boolean releaseQueryResult(int handle);
Expand Down
Loading

0 comments on commit c23ad3f

Please sign in to comment.