Add getContentMetadata and applyContentMetadataMutations to SimpleCache

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=189169899
This commit is contained in:
eguven 2018-03-15 05:00:30 -07:00 committed by Oliver Woodman
parent 10a48e778e
commit bb71b050c9
6 changed files with 75 additions and 29 deletions

View File

@ -144,10 +144,10 @@ public class CachedContentIndexTest extends InstrumentationTestCase {
} }
public void testStore() throws Exception { public void testStore() throws Exception {
CachedContent cachedContent1 = index.getOrAdd("KLMNO"); index.getOrAdd("KLMNO");
cachedContent1.setLength(2560); index.setContentLength("KLMNO", 2560);
CachedContent cachedContent2 = index.getOrAdd("ABCDE"); index.getOrAdd("ABCDE");
cachedContent2.setLength(10); index.setContentLength("ABCDE", 10);
index.store(); index.store();

View File

@ -54,13 +54,12 @@ import java.util.TreeSet;
throws IOException { throws IOException {
int id = input.readInt(); int id = input.readInt();
String key = input.readUTF(); String key = input.readUTF();
CachedContent cachedContent; CachedContent cachedContent = new CachedContent(id, key);
if (version < VERSION_METADATA_INTRODUCED) { if (version < VERSION_METADATA_INTRODUCED) {
cachedContent = new CachedContent(id, key);
long length = input.readLong(); long length = input.readLong();
cachedContent.setLength(length); cachedContent.setLength(length);
} else { } else {
cachedContent = new CachedContent(id, key, DefaultContentMetadata.readFromStream(input)); cachedContent.metadata = DefaultContentMetadata.readFromStream(input);
} }
return cachedContent; return cachedContent;
} }
@ -72,13 +71,9 @@ import java.util.TreeSet;
* @param key The cache stream key. * @param key The cache stream key.
*/ */
public CachedContent(int id, String key) { public CachedContent(int id, String key) {
this(id, key, new DefaultContentMetadata());
}
private CachedContent(int id, String key, DefaultContentMetadata metadata) {
this.id = id; this.id = id;
this.key = key; this.key = key;
this.metadata = metadata; this.metadata = DefaultContentMetadata.EMPTY;
this.cachedSpans = new TreeSet<>(); this.cachedSpans = new TreeSet<>();
} }
@ -94,6 +89,16 @@ import java.util.TreeSet;
metadata.writeToStream(output); metadata.writeToStream(output);
} }
/** Returns the metadata. */
public ContentMetadata getMetadata() {
return metadata;
}
/** Applies {@code mutations} to the metadata. */
public void applyMetadataMutations(ContentMetadataMutations mutations) {
this.metadata = new DefaultContentMetadata(metadata, mutations);
}
/** /**
* Returns the length of the original stream, or {@link C#LENGTH_UNSET} if the length is unknown. * Returns the length of the original stream, or {@link C#LENGTH_UNSET} if the length is unknown.
*/ */
@ -103,9 +108,7 @@ import java.util.TreeSet;
/** Sets the length of the content. */ /** Sets the length of the content. */
public void setLength(long length) { public void setLength(long length) {
ContentMetadataMutations mutations = applyMetadataMutations(new ContentMetadataMutations().set(METADATA_NAME_LENGTH, length));
new ContentMetadataMutations().set(METADATA_NAME_LENGTH, length);
metadata = new DefaultContentMetadata(metadata, mutations);
} }
/** Returns whether the content is locked. */ /** Returns whether the content is locked. */

View File

@ -218,6 +218,21 @@ import javax.crypto.spec.SecretKeySpec;
return cachedContent == null ? C.LENGTH_UNSET : cachedContent.getLength(); return cachedContent == null ? C.LENGTH_UNSET : cachedContent.getLength();
} }
/**
* Applies {@code mutations} to the {@link ContentMetadata} for the given key. A new {@link
* CachedContent} is added if there isn't one already with the given key.
*/
public void applyContentMetadataMutations(String key, ContentMetadataMutations mutations) {
CachedContent cachedContent = getOrAdd(key);
cachedContent.applyMetadataMutations(mutations);
}
/** Returns a snapshot of the {@link ContentMetadata} for the given key. */
public ContentMetadata getContentMetadataSnapshot(String key) {
CachedContent cachedContent = get(key);
return cachedContent != null ? cachedContent.getMetadata() : DefaultContentMetadata.EMPTY;
}
private boolean readFile() { private boolean readFile() {
DataInputStream input = null; DataInputStream input = null;
try { try {

View File

@ -31,6 +31,10 @@ import java.util.Map.Entry;
/** Default implementation of {@link ContentMetadata}. Values are stored as byte arrays. */ /** Default implementation of {@link ContentMetadata}. Values are stored as byte arrays. */
public final class DefaultContentMetadata implements ContentMetadata { public final class DefaultContentMetadata implements ContentMetadata {
/** An empty DefaultContentMetadata. */
public static final DefaultContentMetadata EMPTY =
new DefaultContentMetadata(Collections.<String, byte[]>emptyMap());
private static final int MAX_VALUE_LENGTH = 10 * 1024 * 1024; private static final int MAX_VALUE_LENGTH = 10 * 1024 * 1024;
private int hashCode; private int hashCode;
@ -59,11 +63,6 @@ public final class DefaultContentMetadata implements ContentMetadata {
private final Map<String, byte[]> metadata; private final Map<String, byte[]> metadata;
/** Constructs an empty {@link DefaultContentMetadata}. */
public DefaultContentMetadata() {
this(Collections.<String, byte[]>emptyMap());
}
/** /**
* Constructs a {@link DefaultContentMetadata} by copying metadata values from {@code other} and * Constructs a {@link DefaultContentMetadata} by copying metadata values from {@code other} and
* applying {@code mutations}. * applying {@code mutations}.
@ -165,13 +164,20 @@ public final class DefaultContentMetadata implements ContentMetadata {
private static Map<String, byte[]> applyMutations( private static Map<String, byte[]> applyMutations(
Map<String, byte[]> otherMetadata, ContentMetadataMutations mutations) { Map<String, byte[]> otherMetadata, ContentMetadataMutations mutations) {
HashMap<String, byte[]> metadata = new HashMap<>(otherMetadata); HashMap<String, byte[]> metadata = new HashMap<>(otherMetadata);
List<String> removedValues = mutations.getRemovedValues(); removeValues(metadata, mutations.getRemovedValues());
for (int i = 0; i < removedValues.size(); i++) { addValues(metadata, mutations.getEditedValues());
metadata.remove(removedValues.get(i)); return metadata;
}
private static void removeValues(HashMap<String, byte[]> metadata, List<String> names) {
for (int i = 0; i < names.size(); i++) {
metadata.remove(names.get(i));
} }
Map<String, Object> editedValues = mutations.getEditedValues(); }
for (String name : editedValues.keySet()) {
Object value = editedValues.get(name); private static void addValues(HashMap<String, byte[]> metadata, Map<String, Object> values) {
for (String name : values.keySet()) {
Object value = values.get(name);
byte[] bytes = getBytes(value); byte[] bytes = getBytes(value);
if (bytes.length > MAX_VALUE_LENGTH) { if (bytes.length > MAX_VALUE_LENGTH) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
@ -181,7 +187,6 @@ public final class DefaultContentMetadata implements ContentMetadata {
} }
metadata.put(name, bytes); metadata.put(name, bytes);
} }
return metadata;
} }
private static byte[] getBytes(Object value) { private static byte[] getBytes(Object value) {

View File

@ -412,4 +412,27 @@ public final class SimpleCache implements Cache {
return index.getContentLength(key); return index.getContentLength(key);
} }
/**
* Applies {@code mutations} to the {@link ContentMetadata} for the given key. A new {@link
* CachedContent} is added if there isn't one already with the given key.
*
* @param key The cache key for the data.
* @param mutations Contains mutations to be applied to the metadata.
* @throws CacheException If an error is encountered.
*/
public void applyContentMetadataMutations(String key, ContentMetadataMutations mutations)
throws CacheException {
index.applyContentMetadataMutations(key, mutations);
index.store();
}
/**
* Returns a snapshot of the {@link ContentMetadata} for the given key.
*
* @param key The cache key for the data.
* @return A snapshot of the {@link ContentMetadata} for the given key.
*/
public ContentMetadata getContentMetadataSnapshot(String key) {
return index.getContentMetadataSnapshot(key);
}
} }

View File

@ -62,7 +62,7 @@ public class DefaultContentMetadataTest {
@Test @Test
public void testEmptyMutationDoesNotFail() throws Exception { public void testEmptyMutationDoesNotFail() throws Exception {
ContentMetadataMutations mutations = new ContentMetadataMutations(); ContentMetadataMutations mutations = new ContentMetadataMutations();
new DefaultContentMetadata(new DefaultContentMetadata(), mutations); new DefaultContentMetadata(DefaultContentMetadata.EMPTY, mutations);
} }
@Test @Test
@ -194,6 +194,6 @@ public class DefaultContentMetadataTest {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
} }
return new DefaultContentMetadata(new DefaultContentMetadata(), mutations); return new DefaultContentMetadata(DefaultContentMetadata.EMPTY, mutations);
} }
} }