|  | @@ -2,7 +2,7 @@ package collect
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  import (
 |  |  import (
 | 
											
												
													
														|  |  	"sync"
 |  |  	"sync"
 | 
											
												
													
														|  | -	"time"
 |  | 
 | 
											
												
													
														|  | 
 |  | +	"sync/atomic"
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  	"github.com/v2ray/v2ray-core/common/serial"
 |  |  	"github.com/v2ray/v2ray-core/common/serial"
 | 
											
												
													
														|  |  )
 |  |  )
 | 
											
										
											
												
													
														|  | @@ -18,39 +18,35 @@ type entry struct {
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  type ValidityMap struct {
 |  |  type ValidityMap struct {
 | 
											
												
													
														|  |  	sync.RWMutex
 |  |  	sync.RWMutex
 | 
											
												
													
														|  | -	cache              map[string]Validity
 |  | 
 | 
											
												
													
														|  | -	cleanupIntervalSec int
 |  | 
 | 
											
												
													
														|  | 
 |  | +	cache   map[string]Validity
 | 
											
												
													
														|  | 
 |  | +	opCount int32
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  func NewValidityMap(cleanupIntervalSec int) *ValidityMap {
 |  |  func NewValidityMap(cleanupIntervalSec int) *ValidityMap {
 | 
											
												
													
														|  |  	instance := &ValidityMap{
 |  |  	instance := &ValidityMap{
 | 
											
												
													
														|  | -		cache:              make(map[string]Validity),
 |  | 
 | 
											
												
													
														|  | -		cleanupIntervalSec: cleanupIntervalSec,
 |  | 
 | 
											
												
													
														|  | 
 |  | +		cache: make(map[string]Validity),
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  | -	go instance.cleanup()
 |  | 
 | 
											
												
													
														|  |  	return instance
 |  |  	return instance
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  func (this *ValidityMap) cleanup() {
 |  |  func (this *ValidityMap) cleanup() {
 | 
											
												
													
														|  | -	for range time.Tick(time.Duration(this.cleanupIntervalSec) * time.Second) {
 |  | 
 | 
											
												
													
														|  | -		entry2Remove := make([]entry, 0, 128)
 |  | 
 | 
											
												
													
														|  | -		this.RLock()
 |  | 
 | 
											
												
													
														|  | -		for key, value := range this.cache {
 |  | 
 | 
											
												
													
														|  | -			if !value.IsValid() {
 |  | 
 | 
											
												
													
														|  | -				entry2Remove = append(entry2Remove, entry{
 |  | 
 | 
											
												
													
														|  | -					key:   key,
 |  | 
 | 
											
												
													
														|  | -					value: value,
 |  | 
 | 
											
												
													
														|  | -				})
 |  | 
 | 
											
												
													
														|  | -			}
 |  | 
 | 
											
												
													
														|  | 
 |  | +	entry2Remove := make([]entry, 0, 128)
 | 
											
												
													
														|  | 
 |  | +	this.RLock()
 | 
											
												
													
														|  | 
 |  | +	for key, value := range this.cache {
 | 
											
												
													
														|  | 
 |  | +		if !value.IsValid() {
 | 
											
												
													
														|  | 
 |  | +			entry2Remove = append(entry2Remove, entry{
 | 
											
												
													
														|  | 
 |  | +				key:   key,
 | 
											
												
													
														|  | 
 |  | +				value: value,
 | 
											
												
													
														|  | 
 |  | +			})
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  | -		this.RUnlock()
 |  | 
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +	this.RUnlock()
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -		for _, entry := range entry2Remove {
 |  | 
 | 
											
												
													
														|  | -			if !entry.value.IsValid() {
 |  | 
 | 
											
												
													
														|  | -				this.Lock()
 |  | 
 | 
											
												
													
														|  | -				delete(this.cache, entry.key)
 |  | 
 | 
											
												
													
														|  | -				this.Unlock()
 |  | 
 | 
											
												
													
														|  | -			}
 |  | 
 | 
											
												
													
														|  | 
 |  | +	for _, entry := range entry2Remove {
 | 
											
												
													
														|  | 
 |  | +		if !entry.value.IsValid() {
 | 
											
												
													
														|  | 
 |  | +			this.Lock()
 | 
											
												
													
														|  | 
 |  | +			delete(this.cache, entry.key)
 | 
											
												
													
														|  | 
 |  | +			this.Unlock()
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
										
											
												
													
														|  | @@ -59,6 +55,11 @@ func (this *ValidityMap) Set(key serial.String, value Validity) {
 | 
											
												
													
														|  |  	this.Lock()
 |  |  	this.Lock()
 | 
											
												
													
														|  |  	this.cache[key.String()] = value
 |  |  	this.cache[key.String()] = value
 | 
											
												
													
														|  |  	this.Unlock()
 |  |  	this.Unlock()
 | 
											
												
													
														|  | 
 |  | +	opCount := atomic.AddInt32(&this.opCount, 1)
 | 
											
												
													
														|  | 
 |  | +	if opCount > 1000 {
 | 
											
												
													
														|  | 
 |  | +		atomic.StoreInt32(&this.opCount, 0)
 | 
											
												
													
														|  | 
 |  | +		go this.cleanup()
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  func (this *ValidityMap) Get(key serial.String) Validity {
 |  |  func (this *ValidityMap) Get(key serial.String) Validity {
 |