Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 67fed015 authored by Brad Fitzpatrick's avatar Brad Fitzpatrick
Browse files

Avoid unnecessary SharedPrefences disk writes.

Apps commonly edit + commit redundant changes to their
SharedPreferences, not checking the existing values.  Rather than
force all apps to double-check that their settings writes aren't
redundant, we should just make .commit() faster (avoiding the disk
write) when the file already exists on disk and no effective changes
were made.

Change-Id: I7edbd0d3ace5b69b7af6d12c39797c8b7f86230b
parent b3e957bb
Loading
Loading
Loading
Loading
+28 −6
Original line number Diff line number Diff line
@@ -2844,6 +2844,7 @@ class ContextImpl extends Context {
                boolean returnValue;

                boolean hasListeners;
                boolean changesMade = false;
                List<String> keysModified = null;
                Set<OnSharedPreferenceChangeListener> listeners = null;

@@ -2857,17 +2858,31 @@ class ContextImpl extends Context {

                    synchronized (this) {
                        if (mClear) {
                            if (!mMap.isEmpty()) {
                                changesMade = true;
                                mMap.clear();
                            }
                            mClear = false;
                        }

                        for (Entry<String, Object> e : mModified.entrySet()) {
                            String k = e.getKey();
                            Object v = e.getValue();
                            if (v == this) {
                            if (v == this) {  // magic value for a removal mutation
                                if (mMap.containsKey(k)) {
                                    mMap.remove(k);
                                    changesMade = true;
                                }
                            } else {
                                boolean isSame = false;
                                if (mMap.containsKey(k)) {
                                    Object existingValue = mMap.get(k);
                                    isSame = existingValue != null && existingValue.equals(v);
                                }
                                if (!isSame) {
                                    mMap.put(k, v);
                                    changesMade = true;
                                }
                            }

                            if (hasListeners) {
@@ -2878,7 +2893,7 @@ class ContextImpl extends Context {
                        mModified.clear();
                    }

                    returnValue = writeFileLocked();
                    returnValue = writeFileLocked(changesMade);
                }

                if (hasListeners) {
@@ -2923,9 +2938,16 @@ class ContextImpl extends Context {
            return str;
        }

        private boolean writeFileLocked() {
        private boolean writeFileLocked(boolean changesMade) {
            // Rename the current file so it may be used as a backup during the next read
            if (mFile.exists()) {
                if (!changesMade) {
                    // If the file already exists, but no changes were
                    // made to the underlying map, it's wasteful to
                    // re-write the file.  Return as if we wrote it
                    // out.
                    return true;
                }
                if (!mBackupFile.exists()) {
                    if (!mFile.renameTo(mBackupFile)) {
                        Log.e(TAG, "Couldn't rename file " + mFile