⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cache.java

📁 DNS Java 是java实现的DNS
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)package org.xbill.DNS;import java.io.*;import java.util.*;/** * A cache of DNS records.  The cache obeys TTLs, so items are purged after * their validity period is complete.  Negative answers are cached, to * avoid repeated failed DNS queries.  The credibility of each RRset is * maintained, so that more credible records replace less credible records, * and lookups can specify the minimum credibility of data they are requesting. * @see RRset * @see Credibility * * @author Brian Wellington */public class Cache {private interface Element {	public boolean expired();	public int compareCredibility(int cred);	public int getType();}private static intlimitExpire(long ttl, long maxttl) {	if (maxttl >= 0 && maxttl < ttl)		ttl = maxttl;	int expire = (int)((System.currentTimeMillis() / 1000) + ttl);	if (expire < 0 || expire > Integer.MAX_VALUE)		return Integer.MAX_VALUE;	return expire;}private static class CacheRRset extends RRset implements Element {	int credibility;	int expire;	public	CacheRRset(Record rec, int cred, long maxttl) {		super();		this.credibility = cred;		this.expire = limitExpire(rec.getTTL(), maxttl);		addRR(rec);	}	public	CacheRRset(RRset rrset, int cred, long maxttl) {		super(rrset);		this.credibility = cred;		this.expire = limitExpire(rrset.getTTL(), maxttl);	}	public final boolean	expired() {		int now = (int)(System.currentTimeMillis() / 1000);		return (now >= expire);	}	public final int	compareCredibility(int cred) {		return credibility - cred;	}	public String	toString() {		StringBuffer sb = new StringBuffer();		sb.append(super.toString());		sb.append(" cl = ");		sb.append(credibility);		return sb.toString();	}}private static class NegativeElement implements Element {	int type;	Name name;	SOARecord soa;	int credibility;	int expire;	public	NegativeElement(Name name, int type, SOARecord soa, int cred,			long maxttl)	{		this.name = name;		this.type = type;		this.soa = soa;		long cttl = 0;		if (soa != null)			cttl = soa.getMinimum();		this.credibility = cred;		this.expire = limitExpire(cttl, maxttl);	}	public int	getType() {		return type;	}	public final boolean	expired() {		int now = (int)(System.currentTimeMillis() / 1000);		return (now >= expire);	}	public final int	compareCredibility(int cred) {		return credibility - cred;	}	public String	toString() {		StringBuffer sb = new StringBuffer();		if (type == 0)			sb.append("NXDOMAIN " + name);		else			sb.append("NXRRSET " + name + " " + Type.string(type));		sb.append(" cl = ");		sb.append(credibility);		return sb.toString();	}}private static class CacheMap extends LinkedHashMap {	private int maxsize = -1;	CacheMap(int maxsize) {		super(16, (float) 0.75, true);		this.maxsize = maxsize;	}	int	getMaxSize() {		return maxsize;	}	void	setMaxSize(int maxsize) {		/*		 * Note that this doesn't shrink the size of the map if		 * the maximum size is lowered, but it should shrink as		 * entries expire.		 */		this.maxsize = maxsize;	}	protected boolean removeEldestEntry(Map.Entry eldest) {		return maxsize >= 0 && size() > maxsize;	}}private CacheMap data;private int maxncache = -1;private int maxcache = -1;private int dclass;private static final int defaultMaxEntries = 50000;/** * Creates an empty Cache * * @param dclass The DNS class of this cache * @see DClass */publicCache(int dclass) {	this.dclass = dclass;	data = new CacheMap(defaultMaxEntries);}/** * Creates an empty Cache for class IN. * @see DClass */publicCache() {	this(DClass.IN);}/** * Creates a Cache which initially contains all records in the specified file. */publicCache(String file) throws IOException {	data = new CacheMap(defaultMaxEntries);	Master m = new Master(file);	Record record;	while ((record = m.nextRecord()) != null)		addRecord(record, Credibility.HINT, m);}private synchronized ObjectexactName(Name name) {	return data.get(name);}private synchronized voidremoveName(Name name) {	data.remove(name);}private synchronized Element []allElements(Object types) {	if (types instanceof List) {		List typelist = (List) types;		int size = typelist.size();		return (Element []) typelist.toArray(new Element[size]);	} else {		Element set = (Element) types;		return new Element[] {set};	}}private synchronized ElementoneElement(Name name, Object types, int type, int minCred) {	Element found = null;	if (type == Type.ANY)		throw new IllegalArgumentException("oneElement(ANY)");	if (types instanceof List) {		List list = (List) types;		for (int i = 0; i < list.size(); i++) {			Element set = (Element) list.get(i);			if (set.getType() == type) {				found = set;				break;			}		}	} else {		Element set = (Element) types;		if (set.getType() == type)			found = set;	}	if (found == null)		return null;	if (found.expired()) {		removeElement(name, type);		return null;	}	if (found.compareCredibility(minCred) < 0)		return null;	return found;}private synchronized ElementfindElement(Name name, int type, int minCred) {	Object types = exactName(name);	if (types == null)		return null;	return oneElement(name, types, type, minCred);}private synchronized voidaddElement(Name name, Element element) {	Object types = data.get(name);	if (types == null) {		data.put(name, element);		return;	}	int type = element.getType();	if (types instanceof List) {		List list = (List) types;		for (int i = 0; i < list.size(); i++) {			Element elt = (Element) list.get(i);			if (elt.getType() == type) {				list.set(i, element);				return;			}		}		list.add(element);	} else {		Element elt = (Element) types;		if (elt.getType() == type)			data.put(name, element);		else {			LinkedList list = new LinkedList();			list.add(elt);			list.add(element);			data.put(name, list);		}	}}private synchronized voidremoveElement(Name name, int type) {	Object types = data.get(name);	if (types == null) {		return;	}	if (types instanceof List) {		List list = (List) types;		for (int i = 0; i < list.size(); i++) {			Element elt = (Element) list.get(i);			if (elt.getType() == type) {				list.remove(i);				if (list.size() == 0)					data.remove(name);				return;			}		}	} else {		Element elt = (Element) types;		if (elt.getType() != type)			return;		data.remove(name);	}}/** Empties the Cache. */public synchronized voidclearCache() {	data.clear();}/** * Adds a record to the Cache. * @param r The record to be added * @param cred The credibility of the record * @param o The source of the record (this could be a Message, for example) * @see Record */public synchronized voidaddRecord(Record r, int cred, Object o) {	Name name = r.getName();	int type = r.getRRsetType();	if (!Type.isRR(type))		return;	Element element = findElement(name, type, cred);	if (element == null) {		CacheRRset crrset = new CacheRRset(r, cred, maxcache);		addRRset(crrset, cred);	} else if (element.compareCredibility(cred) == 0) {		if (element instanceof CacheRRset) {			CacheRRset crrset = (CacheRRset) element;			crrset.addRR(r);		}	}}/** * Adds an RRset to the Cache. * @param rrset The RRset to be added * @param cred The credibility of these records * @see RRset */public synchronized voidaddRRset(RRset rrset, int cred) {	long ttl = rrset.getTTL();	Name name = rrset.getName();	int type = rrset.getType();	Element element = findElement(name, type, 0);	if (ttl == 0) {		if (element != null && element.compareCredibility(cred) <= 0)			removeElement(name, type);	} else {		if (element != null && element.compareCredibility(cred) <= 0)			element = null;		if (element == null) {			CacheRRset crrset;			if (rrset instanceof CacheRRset)				crrset = (CacheRRset) rrset;			else				crrset = new CacheRRset(rrset, cred, maxcache);			addElement(name, crrset);		}	}}/** * Adds a negative entry to the Cache. * @param name The name of the negative entry * @param type The type of the negative entry * @param soa The SOA record to add to the negative cache entry, or null. * The negative cache ttl is derived from the SOA. * @param cred The credibility of the negative entry */public synchronized voidaddNegative(Name name, int type, SOARecord soa, int cred) {	long ttl = 0;	if (soa != null)		ttl = soa.getTTL();	Element element = findElement(name, type, 0);	if (ttl == 0) {		if (element != null && element.compareCredibility(cred) <= 0)			removeElement(name, type);	} else {		if (element != null && element.compareCredibility(cred) <= 0)			element = null;		if (element == null)			addElement(name, new NegativeElement(name, type,							     soa, cred,							     maxncache));	}}/** * Finds all matching sets or something that causes the lookup to stop. */protected synchronized SetResponselookup(Name name, int type, int minCred) {	int labels;	int tlabels;	Element element;	CacheRRset crrset;	Name tname;	Object types;	SetResponse sr;	labels = name.labels();	for (tlabels = labels; tlabels >= 1; tlabels--) {		boolean isRoot = (tlabels == 1);		boolean isExact = (tlabels == labels);		if (isRoot)			tname = Name.root;		else if (isExact)			tname = name;		else			tname = new Name(name, labels - tlabels);		types = data.get(tname);		if (types == null)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -