/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package my.home.common;

import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;

import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by legendmohe on 15/3/31.
 */
public abstract class CacheKeyValueStorageImpl implements KeyValueStorage.IKeyStringStorge {
    public static final String TAG = "CacheKeyValueStorage";

    private final int MSG_STORAGE_WHAT = 0;

    class CacheHandlerThread extends HandlerThread implements Handler.Callback {
        public CacheHandlerThread(String name) {
            super(name);
        }

        @Override
        public boolean handleMessage(Message msg) {
            Bundle bundle = msg.getData();
//            Log.d(TAG, "run msg: " + bundle.toString());
            storagePutString(bundle.getString("key"), bundle.getString("value"));
            return false;
        }
    }

    final ConcurrentHashMap<String, String> mCache = new ConcurrentHashMap<>();
    private Handler mHandler;

    public CacheKeyValueStorageImpl() {
        CacheHandlerThread cacheHandlerThread = new CacheHandlerThread("CacheKeyValueStorageImpl");
        cacheHandlerThread.setPriority(Thread.MIN_PRIORITY);
        cacheHandlerThread.start();
        mHandler = new Handler(cacheHandlerThread.getLooper(), cacheHandlerThread);
    }

    @Override
    public boolean hasKey(String key) {
        if (mCache.containsKey(key))
            return true;
        return storageHasKey(key);
    }

    @Override
    public void putString(String key, String value) {
        mCache.put(key, value);

        Bundle bundle = new Bundle();
        bundle.putString("key", key);
        bundle.putString("value", value);
        Message msg = new Message();
        msg.what = MSG_STORAGE_WHAT;
        msg.setData(bundle);

        synchronized (mHandler) {
            mHandler.removeMessages(MSG_STORAGE_WHAT);
            mHandler.sendMessageDelayed(msg, 300);
        }
    }

    @Override
    public String getString(String key) {
        if (mCache.containsKey(key))
            return mCache.get(key);
        String value = storageGetString(key);
        if (value != null)
            mCache.put(key, value);
        return value;
    }

    public abstract boolean storageHasKey(String key);

    public abstract void storagePutString(String key, String value);

    public abstract String storageGetString(String key);
}

@@ -1236,112 +1236,102 @@
     
-    Bundle bundle = msg.getData();%0A//            Log.d(TAG, %22run msg: %22 + bundle.toString());%0A  
+%09synchronized (mSyncLock) %7B%0A%09        %09for (String keyString : mSyncCache.keySet()) %7B%0A%09
         
   st
@@ -1326,18 +1326,18 @@
         
-  
+%09%09
 storageP
@@ -1349,40 +1349,140 @@
 ing(
-bundl
+keyString, mSyncCach
 e.get
+(key
 String
-(%22key%22),
+));%0A%09%09%09%09%7D%0A%09        %09mSyncCache.clear();%0A        %09%7D%0A//            Log.d(TAG, %22run msg: %22 +
  bundle.
 getS
@@ -1481,25 +1481,17 @@
 dle.
-ge
 t
+o
 String(
-%22value%22
 ));%0A
@@ -1609,24 +1609,159 @@
 ashMap%3C%3E();%0A
+    final ConcurrentHashMap%3CString, String%3E mSyncCache = new ConcurrentHashMap%3C%3E();%0A    private final Object mSyncLock = new Object();%0A
     private 
@@ -2370,126 +2370,8 @@
 );%0A%0A
-        Bundle bundle = new Bundle();%0A        bundle.putString(%22key%22, key);%0A        bundle.putString(%22value%22, value);%0A
     
@@ -2391,20 +2391,16 @@
 sg =
- new
  Message
 ();%0A
@@ -2395,16 +2395,23 @@
  Message
+.obtain
 ();%0A    
@@ -2443,24 +2443,25 @@
 E_WHAT;%0A
+%0A
         
 msg.setD
@@ -2456,63 +2456,71 @@
     
-msg.setData(bundle);%0A%0A        synchronized (mHandler) %7B
+synchronized (mSyncLock) %7B%0A        %09mSyncCache.put(key, value);
 %0A   
@@ -2900,24 +2900,148 @@
 value;%0A    %7D
+%0A    %0A    @Override%0A    public void removeString(String key) %7B%0A    %09mCache.remove(key);%0A    %09storageRemoveString(key);%0A    %7D
 %0A%0A    public
@@ -3213,10 +3213,73 @@
 g key);%0A
+    %0A    public abstract void storageRemoveString(String key);%0A
 %7D%0A

Update CacheKeyValueStorageImpl.java