SettingsProvider 의 SettingsCache
4867 단어 SettingsCache
SettingsCache 는 SettingsProvider 의 버퍼 를 표시 합 니 다.현재 요청 한 키 값 과 value 를 버퍼 링 합 니 다.이 버퍼 는 메모리 에 있어 서 읽 기 효율 이 비교적 높다.
SettingsProvider 는 다 중 사용자 개념 을 지원 합 니 다. 사용자 마다 최소 세 장의 표 (System, Secure) 가 있 고 모든 표 에는 하나의 SettingsCache 가 존재 합 니 다.
1. 핸드폰 이 시 작 될 때 SettingsProvider 에 대응 하 는 데이터베이스 에 있 는 데이터 시트 의 내용 을 버퍼 링 합 니 다.
private void fullyPopulateCache(DatabaseHelper dbHelper, String table, SettingsCache cache) {
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor c = db.query(
table,
new String[] { Settings.NameValueTable.NAME, Settings.NameValueTable.VALUE },
null, null, null, null, null,
"" + (MAX_CACHE_ENTRIES + 1) /* limit */);
try {
synchronized (cache) {
cache.evictAll();
cache.setFullyMatchesDisk(true); // optimistic
int rows = 0;
while (c.moveToNext()) {
rows++;
String name = c.getString(0);
String value = c.getString(1);
cache.populate(name, value);
}
if (rows > MAX_CACHE_ENTRIES) {
// Somewhat redundant, as removeEldestEntry() will
// have already done this, but to be explicit:
cache.setFullyMatchesDisk(false);
Log.d(TAG, "row count exceeds max cache entries for table " + table);
}
if (LOCAL_LOGV) Log.d(TAG, "cache for settings table '" + table
+ "' rows=" + rows + "; fullycached=" + cache.fullyMatchesDisk());
}
} finally {
c.close();
}
}
2、SettingsCache extends LruCache
/**
* In-memory LRU Cache of system and secure settings, along with
* associated helper functions to keep cache coherent with the
* database.
* System,Secure , 。
*/
private boolean mCacheFullyMatchesDisk = false; // has the whole database slurped. LRU
cache.evictAll();//remove , entryRemoved(true,key,value)
3. putIfAbsent 방법
/**
* Atomic cache population, conditional on size of value and if
* we lost a race.
*
* @returns a Bundle to send back to the client from call(), even
* if we lost the race.
*/
public Bundle putIfAbsent(String key, String value) {
Bundle bundle = (value == null) ? NULL_SETTING : Bundle.forPair("value", value);
if (value == null || value.length() <= MAX_CACHE_ENTRY_SIZE) {// value null, value 500
synchronized (this) {
if (get(key) == null) {
put(key, bundle);//bundle :NULL_SETTINGS、Bundle.forPair("value", value)
}
}
}//【value null, value 500, bundle,bundle Bundle.forPair("value", value)】
return bundle;
}
4. populate (충전)
/**
* Populates a key in a given (possibly-null) cache.
* cache
*/
public static void populate(SettingsCache cache, ContentValues contentValues) {
if (cache == null) {
return;
}
String name = contentValues.getAsString(Settings.NameValueTable.NAME);
if (name == null) {
Log.w(TAG, "null name populating settings cache.");
return;
}
String value = contentValues.getAsString(Settings.NameValueTable.VALUE);
cache.populate(name, value);
}
5. 반복 검사
/**
* For suppressing duplicate/redundant settings inserts early,
* checking our cache first (but without faulting it in),
* before going to sqlite with the mutation.
* , 。 sqlite , cache
* 。
*/
public static boolean isRedundantSetValue(SettingsCache cache, String name, String value) {
if (cache == null) return false;
synchronized (cache) {
Bundle bundle = cache.get(name);
if (bundle == null) return false;
String oldValue = bundle.getPairValue();
if (oldValue == null && value == null) return true;
if ((oldValue == null) != (value == null)) return false;//
return oldValue.equals(value);
}
}