From 1ec571417426c8eccbbf9a0e1378447ec8895fda Mon Sep 17 00:00:00 2001 From: Sergey Solovyev Date: Fri, 26 May 2017 22:54:08 +0200 Subject: [PATCH] Cache mapped values and objects --- .../solovyev/android/prefs/CachingMapper.java | 63 +++++++++++++++++++ .../android/prefs/StringPreference.java | 2 +- .../org/solovyev/common/text/EnumMapper.java | 5 +- .../solovyev/common/text/NumberMapper.java | 8 ++- 4 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/org/solovyev/android/prefs/CachingMapper.java diff --git a/app/src/main/java/org/solovyev/android/prefs/CachingMapper.java b/app/src/main/java/org/solovyev/android/prefs/CachingMapper.java new file mode 100644 index 00000000..be360ffc --- /dev/null +++ b/app/src/main/java/org/solovyev/android/prefs/CachingMapper.java @@ -0,0 +1,63 @@ +package org.solovyev.android.prefs; + +import android.support.annotation.NonNull; +import android.text.TextUtils; + +import org.solovyev.common.text.Mapper; + +import java.util.Objects; + +import javax.annotation.Nullable; + +public final class CachingMapper implements Mapper { + + private static class CachedEntry { + @Nullable + private String value; + @Nullable + private T object; + } + + @NonNull + private final Mapper mapper; + @Nullable + private CachedEntry cachedEntry = null; + + private CachingMapper(@NonNull Mapper mapper) { + this.mapper = mapper; + } + + @NonNull + public static Mapper of(@NonNull Mapper mapper) { + if (mapper.getClass().equals(CachingMapper.class)) { + return mapper; + } + return new CachingMapper<>(mapper); + } + + @Nullable + @Override + public synchronized T parseValue(@Nullable String value) throws IllegalArgumentException { + if (cachedEntry == null) { + cachedEntry = new CachedEntry<>(); + } else if (TextUtils.equals(cachedEntry.value, value)) { + return cachedEntry.object; + } + cachedEntry.value = value; + cachedEntry.object = mapper.parseValue(value); + return cachedEntry.object; + } + + @Nullable + @Override + public synchronized String formatValue(@Nullable T object) throws IllegalArgumentException { + if (cachedEntry == null) { + cachedEntry = new CachedEntry<>(); + } else if (Objects.equals(cachedEntry.object, object)) { + return cachedEntry.value; + } + cachedEntry.object = object; + cachedEntry.value = mapper.formatValue(object); + return cachedEntry.value; + } +} diff --git a/app/src/main/java/org/solovyev/android/prefs/StringPreference.java b/app/src/main/java/org/solovyev/android/prefs/StringPreference.java index 0c561e72..3e6c1486 100644 --- a/app/src/main/java/org/solovyev/android/prefs/StringPreference.java +++ b/app/src/main/java/org/solovyev/android/prefs/StringPreference.java @@ -43,7 +43,7 @@ public final class StringPreference extends AbstractPreference { public StringPreference(@Nonnull String key, @Nullable T defaultValue, @Nonnull Mapper mapper) { super(key, defaultValue); - this.mapper = mapper; + this.mapper = CachingMapper.of(mapper); } @Nonnull diff --git a/app/src/main/java/org/solovyev/common/text/EnumMapper.java b/app/src/main/java/org/solovyev/common/text/EnumMapper.java index 594aa101..62bdca0c 100644 --- a/app/src/main/java/org/solovyev/common/text/EnumMapper.java +++ b/app/src/main/java/org/solovyev/common/text/EnumMapper.java @@ -22,11 +22,12 @@ package org.solovyev.common.text; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import java.util.HashMap; import java.util.Map; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + public class EnumMapper implements Mapper { @Nonnull diff --git a/app/src/main/java/org/solovyev/common/text/NumberMapper.java b/app/src/main/java/org/solovyev/common/text/NumberMapper.java index 7ff0c9ce..946048af 100644 --- a/app/src/main/java/org/solovyev/common/text/NumberMapper.java +++ b/app/src/main/java/org/solovyev/common/text/NumberMapper.java @@ -23,13 +23,15 @@ package org.solovyev.common.text; import org.solovyev.android.Check; +import org.solovyev.android.prefs.CachingMapper; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + public class NumberMapper implements Mapper { private static final List> supportedClasses = NumberParser.supportedClasses; @@ -38,7 +40,7 @@ public class NumberMapper implements Mapper { static { for (Class supportedClass : supportedClasses) { - mappers.put(supportedClass, newInstance(supportedClass)); + mappers.put(supportedClass, CachingMapper.of(newInstance(supportedClass))); } }