Abstract data structure TimeoutSet from chouTime.

This commit is contained in:
Chen Yufei
2013-01-01 16:13:39 +08:00
parent 25db7e3aaa
commit bf6a5ab3bf
2 changed files with 52 additions and 40 deletions

View File

@@ -88,7 +88,7 @@ type DomainSet struct {
alwaysBlocked dmSet
alwaysDirect dmSet
chouTime chouBlockTime
chouSet *TimeoutSet
}
func newDomainSet() *DomainSet {
@@ -100,47 +100,12 @@ func newDomainSet() *DomainSet {
ds.alwaysBlocked = newDmSet()
ds.alwaysDirect = newDmSet()
ds.chouTime = chouBlockTime{time: map[string]time.Time{}}
ds.chouSet = NewTimeoutSet(chouTimeout)
return ds
}
var domainSet = newDomainSet()
// Record when is the domain added to chou domain set
type chouBlockTime struct {
sync.RWMutex
time map[string]time.Time
}
func (cb *chouBlockTime) add(dm string) {
now := time.Now()
cb.Lock()
cb.time[dm] = now
cb.Unlock()
debug.Printf("chou domain %s blocked at %v\n", dm, now)
}
func (cb *chouBlockTime) has(dm string) bool {
cb.RLock()
t, ok := cb.time[dm]
cb.RUnlock()
if !ok {
return false
}
if time.Now().Sub(t) > chouTimeout {
cb.del(dm)
return false
}
return true
}
func (cb *chouBlockTime) del(dm string) {
cb.Lock()
delete(cb.time, dm)
cb.Unlock()
debug.Printf("chou domain %s block time unset\n", dm)
}
func (ds *DomainSet) isHostInAlwaysDs(host string) bool {
dm := host2Domain(host)
return ds.alwaysBlocked[dm] || ds.alwaysDirect[dm]
@@ -162,7 +127,7 @@ func (ds *DomainSet) isHostBlocked(host string) bool {
if ds.alwaysBlocked[dm] {
return true
}
if ds.chouTime.has(dm) {
if ds.chouSet.has(dm) {
return true
}
return ds.blocked.has(dm)
@@ -186,10 +151,11 @@ func (ds *DomainSet) isHostChouFeng(host string) bool {
func (ds *DomainSet) addChouHost(host string) bool {
dm := host2Domain(host)
if ds.isHostAlwaysDirect(host) || dm == "localhost" ||
hostIsIP(host) || ds.chouTime.has(dm) {
hostIsIP(host) || ds.chouSet.has(dm) {
return false
}
ds.chouTime.add(dm)
ds.chouSet.add(dm)
debug.Printf("domain %s blocked\n", dm)
return true
}

46
timeoutset.go Normal file
View File

@@ -0,0 +1,46 @@
package main
import (
"sync"
"time"
)
type TimeoutSet struct {
sync.RWMutex
time map[string]time.Time
timeout time.Duration
}
func NewTimeoutSet(timeout time.Duration) *TimeoutSet {
ts := &TimeoutSet{time: make(map[string]time.Time),
timeout: timeout,
}
return ts
}
func (ts *TimeoutSet) add(key string) {
now := time.Now()
ts.Lock()
ts.time[key] = now
ts.Unlock()
}
func (ts *TimeoutSet) has(key string) bool {
ts.RLock()
t, ok := ts.time[key]
ts.RUnlock()
if !ok {
return false
}
if time.Now().Sub(t) > ts.timeout {
ts.del(key)
return false
}
return true
}
func (ts *TimeoutSet) del(key string) {
ts.Lock()
delete(ts.time, key)
ts.Unlock()
}