func (c *caches) removeLocalRR(rr *ResourceRecord) (err error) {
	c.Lock()
	defer c.Unlock()
	ans, ok := c.v[rr.Name]
	if !ok {
		return nil
	}
	for _, an := range ans.v {
		if an.QType != rr.Type {
			continue
		}
		if an.QClass != rr.Class {
			continue
		}
		err = an.msg.RemoveAnswer(rr)
		break
	}
	return err
}
removeLocalRR remove the local ResourceRecord from caches by its name,
type, class, and value.
package dns
import (
	"container/list"
	"fmt"
	"regexp"
	"sync"
	"time"
	"github.com/shuLhan/share/lib/debug"
)
type caches struct {
	sync.Mutex
	v map[string]*answers
	lru *list.List
	pruneDelay time.Duration
	pruneThreshold time.Duration
}
func newCaches(pruneDelay, pruneThreshold time.Duration) (ca *caches) {
	if pruneDelay.Minutes() < 1 {
		pruneDelay = time.Hour
	}
	if pruneThreshold.Minutes() > -1 {
		pruneThreshold = -1 * time.Hour
	}
	ca = &caches{
		v:              make(map[string]*answers),
		lru:            list.New(),
		pruneDelay:     pruneDelay,
		pruneThreshold: pruneThreshold,
	}
	go ca.startWorker()
	return
}
func (c *caches) get(qname string, qtype, qclass uint16) (ans *answers, an *Answer) {
	c.Lock()
	var found bool
	ans, found = c.v[qname]
	if found {
		an, _ = ans.get(qtype, qclass)
		if an != nil {
			if an.ReceivedAt > 0 {
				c.lru.MoveToBack(an.el)
				an.AccessedAt = time.Now().Unix()
			}
		}
	}
	c.Unlock()
	return
}
func (c *caches) list() (list []*Answer) {
	c.Lock()
	for e := c.lru.Front(); e != nil; e = e.Next() {
		list = append(list, e.Value.(*Answer))
	}
	c.Unlock()
	return
}
func (c *caches) prune() (n int) {
	c.Lock()
	exp := time.Now().Add(c.pruneThreshold).Unix()
	e := c.lru.Front()
	for e != nil {
		an := e.Value.(*Answer)
		if an.AccessedAt > exp {
			break
		}
		if debug.Value >= 1 {
			fmt.Printf("dns: - 0:%s\n", an.msg.Question.String())
		}
		next := e.Next()
		_ = c.lru.Remove(e)
		answers, found := c.v[an.QName]
		if found {
			answers.remove(an.QType, an.QClass)
			if len(answers.v) == 0 {
				delete(c.v, an.QName)
			}
		}
		an.clear()
		n++
		e = next
	}
	c.Unlock()
	return n
}
func (c *caches) remove(qname string) (ok bool) {
	c.Lock()
	for e := c.lru.Front(); e != nil; e = e.Next() {
		answer := e.Value.(*Answer)
		if answer.QName != qname {
			continue
		}
		c.lru.Remove(e)
		delete(c.v, qname)
		answer.clear()
		ok = true
		break
	}
	if !ok {
		_, ok = c.v[qname]
		if ok {
			delete(c.v, qname)
		}
	}
	c.Unlock()
	return ok
}