github.com/urso/go-structform@v0.0.2/gotype/symbols.go (about)

     1  package gotype
     2  
     3  type symbolCache struct {
     4  	m   map[string]*symbol
     5  	lst symbolList
     6  	max int
     7  }
     8  
     9  type symbol struct {
    10  	value string
    11  	prev  *symbol
    12  	next  *symbol
    13  }
    14  
    15  type symbolList symbol
    16  
    17  func (c *symbolCache) init(max int) {
    18  	c.max = max
    19  	c.m = make(map[string]*symbol, max)
    20  	c.lst = symbolList{}
    21  	c.lst.prev = (*symbol)(&c.lst)
    22  	c.lst.next = (*symbol)(&c.lst)
    23  }
    24  
    25  func (c *symbolCache) enabled() bool {
    26  	return c.m != nil
    27  }
    28  
    29  func (c *symbolCache) get(in []byte) string {
    30  	if !c.enabled() {
    31  		return string(in)
    32  	}
    33  
    34  	if sym := c.lookup(bytes2Str(in)); sym != nil {
    35  		return sym.value
    36  	}
    37  
    38  	str := string(in)
    39  	c.add(str)
    40  	return str
    41  }
    42  
    43  func (c *symbolCache) lookup(value string) *symbol {
    44  	sym := c.m[value]
    45  	if sym != nil {
    46  		removeLst(sym)
    47  		c.lst.append(sym)
    48  	}
    49  	return sym
    50  }
    51  
    52  func (c *symbolCache) add(value string) {
    53  	if len(c.m) == c.max {
    54  		old := c.lst.pop()
    55  		delete(c.m, old.value)
    56  	}
    57  
    58  	sym := &symbol{value: value}
    59  	c.m[value] = sym
    60  	c.lst.append(sym)
    61  }
    62  
    63  func (l *symbolList) empty() bool {
    64  	s := (*symbol)(l)
    65  	return s.next == s && s.prev == s
    66  }
    67  
    68  func (l *symbolList) append(sym *symbol) {
    69  	head := (*symbol)(l)
    70  
    71  	sym.prev = head.prev
    72  	sym.next = head
    73  	head.prev.next = sym
    74  	head.prev = sym
    75  }
    76  
    77  func (l *symbolList) pop() (sym *symbol) {
    78  	if !l.empty() {
    79  		sym = l.next
    80  		removeLst(sym)
    81  	}
    82  	return
    83  }
    84  
    85  func removeLst(s *symbol) {
    86  	s.prev.next = s.next
    87  	s.next.prev = s.prev
    88  }