summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/database/sqlite/SQLiteDatabase.java2
-rw-r--r--core/java/android/provider/Settings.java89
2 files changed, 46 insertions, 45 deletions
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index ca7cec2..657bbcc 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -1897,7 +1897,7 @@ public class SQLiteDatabase extends SQLiteClosable {
samplePercent = 100;
} else {
samplePercent = (int) (100 * nanos / QUERY_LOG_TIME_IN_NANOS) + 1;
- if (mRandom.nextInt(100) < samplePercent) return;
+ if (mRandom.nextInt(100) >= samplePercent) return;
}
if (sql.length() > QUERY_LOG_SQL_LENGTH) sql = sql.substring(0, QUERY_LOG_SQL_LENGTH);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index c20d338..df40946 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -38,6 +38,7 @@ import android.os.*;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.AndroidException;
+import android.util.Config;
import android.util.Log;
import java.net.URISyntaxException;
@@ -442,6 +443,7 @@ public final class Settings {
public static final String AUTHORITY = "settings";
private static final String TAG = "Settings";
+ private static final boolean LOCAL_LOGV = Config.LOGV || false;
public static class SettingNotFoundException extends AndroidException {
public SettingNotFoundException(String msg) {
@@ -478,61 +480,60 @@ public final class Settings {
private static class NameValueCache {
private final String mVersionSystemProperty;
- // the following needs synchronization because this structure is accessed from different
- // threads and they could be performing clear(), get(), put() at the same time.
- private final Map<String, String> mValues =
- Collections.synchronizedMap(new HashMap<String, String>());
- private long mValuesVersion = 0;
private final Uri mUri;
- NameValueCache(String versionSystemProperty, Uri uri) {
+ // Must synchronize(mValues) to access mValues and mValuesVersion.
+ private final HashMap<String, String> mValues = new HashMap<String, String>();
+ private long mValuesVersion = 0;
+
+ public NameValueCache(String versionSystemProperty, Uri uri) {
mVersionSystemProperty = versionSystemProperty;
mUri = uri;
}
- String getString(ContentResolver cr, String name) {
+ public String getString(ContentResolver cr, String name) {
long newValuesVersion = SystemProperties.getLong(mVersionSystemProperty, 0);
- if (mValuesVersion != newValuesVersion) {
- mValues.clear();
- mValuesVersion = newValuesVersion;
+
+ synchronized (mValues) {
+ if (mValuesVersion != newValuesVersion) {
+ if (LOCAL_LOGV) {
+ Log.v(TAG, "invalidate [" + mUri.getLastPathSegment() + "]: current " +
+ newValuesVersion + " != cached " + mValuesVersion);
+ }
+
+ mValues.clear();
+ mValuesVersion = newValuesVersion;
+ }
+
+ if (mValues.containsKey(name)) {
+ return mValues.get(name); // Could be null, that's OK -- negative caching
+ }
}
- /*
- * don't look for the key using containsKey() method because (key, object) mapping
- * could be removed from mValues before get() is done like so:
- *
- * say, mValues contains mapping for "foo"
- * Thread# 1
- * performs containsKey("foo")
- * receives true
- * Thread #2
- * triggers mValues.clear()
- * Thread#1
- * since containsKey("foo") = true, performs get("foo")
- * receives null
- * thats incorrect!
- *
- * to avoid the above, thread#1 should do get("foo") instead of containsKey("foo")
- * since mValues is synchronized, get() will get a consistent value.
- *
- * we don't want to make this method synchronized tho - because
- * holding mutex is not desirable while a call could be made to database.
- */
- String value = mValues.get(name);
- if (value == null) {
- Cursor c = null;
- try {
- c = cr.query(mUri, new String[] { Settings.NameValueTable.VALUE },
- Settings.NameValueTable.NAME + "=?", new String[]{name}, null);
- if (c != null && c.moveToNext()) value = c.getString(0);
+
+ Cursor c = null;
+ try {
+ c = cr.query(mUri, new String[] { Settings.NameValueTable.VALUE },
+ Settings.NameValueTable.NAME + "=?", new String[]{name}, null);
+ if (c == null) {
+ Log.w(TAG, "Can't get key " + name + " from " + mUri);
+ return null;
+ }
+
+ String value = c.moveToNext() ? c.getString(0) : null;
+ synchronized (mValues) {
mValues.put(name, value);
- } catch (SQLException e) {
- // SQL error: return null, but don't cache it.
- Log.w(TAG, "Can't get key " + name + " from " + mUri, e);
- } finally {
- if (c != null) c.close();
}
+ if (LOCAL_LOGV) {
+ Log.v(TAG, "cache miss [" + mUri.getLastPathSegment() + "]: " +
+ name + " = " + (value == null ? "(null)" : value));
+ }
+ return value;
+ } catch (SQLException e) {
+ Log.w(TAG, "Can't get key " + name + " from " + mUri, e);
+ return null; // Return null, but don't cache it.
+ } finally {
+ if (c != null) c.close();
}
- return value;
}
}