/**
*
*/
package com.sina.util.dnscache.cache;
import android.annotation.SuppressLint;
import android.content.Context;
import android.database.sqlite.SQLiteDatabaseLockedException;
import com.sina.util.dnscache.model.DomainModel;
import com.sina.util.dnscache.model.HttpDnsPack;
import com.sina.util.dnscache.model.IpModel;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import static android.R.id.list;
/**
*
* 项目名称: DNSCache <br>
* 类名称: DnsCacheManager <br>
* 类描述: Dnd缓存层管理类 <br>
* 创建人: fenglei <br>
* 创建时间: 2015-3-26 下午6:10:10 <br>
*
* 修改人: <br>
* 修改时间: <br>
* 修改备注: <br>
*
* @version V1.0
*/
public class DnsCacheManager extends DNSCacheDatabaseHelper implements IDnsCache{
public DnsCacheManager(Context context) {
super(context);
db = new DNSCacheDatabaseHelper(context) ;
}
/**
* 数据库操作类
*/
private DNSCacheDatabaseHelper db = null ;
/**
* 缓存初始容量值
*/
private final int INIT_SIZE = 8;
/**
* 缓存最大容量值
*/
private final int MAX_CACHE_SIZE = 32;
/**
* 延迟差值,单位s
*/
public static int ip_overdue_delay = 20 ;
/**
* 缓存链表
*/
@SuppressLint("NewApi")
private ConcurrentHashMap<String, DomainModel> data = new ConcurrentHashMap<String, DomainModel>(INIT_SIZE, MAX_CACHE_SIZE);
/////////////////////////////////////////////////////////////////////////////////////////////
/**
* 获取url缓存
* @param url
* @return
*/
@Override
public DomainModel getDnsCache(String sp, String url){
DomainModel model = data.get(url) ;
if( model == null ){
//缓存中没有从数据库中查找
ArrayList<DomainModel> list = null;
try {
list = (ArrayList<DomainModel>) db.QueryDomainInfo(url, sp);
} catch(SQLiteDatabaseLockedException e){
e.printStackTrace();
}
if( list != null && list.size() != 0){
model = list.get( list.size() - 1 ) ;
}
//查询到数据 添加到缓存中
if( model != null )addMemoryCache(url, model) ;
}
if( model != null){
//检测是否过期
if( isExpire(model, ip_overdue_delay) ){
model = null ;
}
}
return model ;
}
/**
* 插入本地 cache 缓存
*
* @param dnsPack
* @return
*/
public DomainModel insertDnsCache(HttpDnsPack dnsPack){
DomainModel domainModel = new DomainModel() ;
domainModel.domain = dnsPack.domain ;
domainModel.sp = dnsPack.localhostSp ;
domainModel.time = String.valueOf(System.currentTimeMillis());
domainModel.ipModelArr = new ArrayList<IpModel>();
int domainTTL = 60 ;
for( HttpDnsPack.IP temp : dnsPack.dns ){
IpModel ipModel = new IpModel() ;
ipModel.ip = temp.ip ;
ipModel.ttl = temp.ttl ;
ipModel.priority = temp.priority ;
ipModel.port = 80 ;
ipModel.sp = domainModel.sp ;
domainModel.ipModelArr.add(ipModel) ;
try {
domainTTL = Math.min(domainTTL, Integer.valueOf(ipModel.ttl));
}catch(NumberFormatException e){
}
}
domainModel.ttl = String.valueOf(domainTTL);
if( domainModel != null && domainModel.ipModelArr != null && domainModel.ipModelArr.size() > 0){
// 插入数据库
try {
domainModel = super.addDomainModel(dnsPack.domain, dnsPack.localhostSp, domainModel);
}catch (SQLiteDatabaseLockedException e){
e.printStackTrace();
}
// 插入内存缓存
addMemoryCache( domainModel.domain, domainModel );
}
return domainModel ;
}
/**
* 获取即将过期的 domain 数据
* @return
*/
@Override
public ArrayList<DomainModel> getExpireDnsCache() {
ArrayList<DomainModel> listDomain = new ArrayList<DomainModel>();
for (Entry<String, DomainModel> entry : data.entrySet()) {
DomainModel temp = data.get(entry.getKey());
if (isExpire(temp)) {
listDomain.add(temp);
}
}
return listDomain;
}
/**
* 获取缓存中全部的 DomainModel数据
*/
public ArrayList<DomainModel> getAllMemoryCache() {
ArrayList<DomainModel> list = new ArrayList<DomainModel>() ;
for (Entry<String, DomainModel> entry : data.entrySet()) {
DomainModel temp = data.get(entry.getKey());
list.add(temp) ;
}
return list;
}
/**
* 清除全部缓存
*/
public void clear(){
super.clear();
data.clear();
}
/**
* 清除内存缓存
*/
public void clearMemoryCache(){
data.clear();
}
/////////////////////////////////////////////////////////////////////////////////////////////
/**
* 添加url缓存
* @param model
*/
public void addMemoryCache(String url, DomainModel model) {
if( model == null ) return ;
if( model.ipModelArr == null ) return ;
if( model.ipModelArr.size() <= 0 ) return ;
for( IpModel ipModel : model.ipModelArr ){
if( ipModel == null ) return ;
}
// 检测下缓存中是否存在, 如果存在删除旧数据在添加
DomainModel temp = data.get(url);
if (temp != null) {
data.remove(url);
}
data.put(url, model);
}
/**
* 检测是否过期,提前3秒刷一下
* @param domainModel
* @return
*/
private boolean isExpire(DomainModel domainModel) {
return isExpire(domainModel, -3);
}
/**
* 检测是否过期
*
* @param domainModel
* @return
*/
private boolean isExpire(DomainModel domainModel, long difference) {
long queryTime = Long.parseLong(domainModel.time) / 1000;
long ttl = Long.parseLong(domainModel.ttl);
long newTime = System.currentTimeMillis() / 1000;
if ((newTime - queryTime) > (ttl + difference)) {
return true;
}
return false;
}
@Override
public void setSpeedInfo(List<IpModel> ipModels) {
updateIpInfo(ipModels);
}
/////////////////////////////////////////////////////////////////////////////////////////////
}