github.com/whatap/golib@v0.0.22/util/hmap/IntSet.go (about)

     1  package hmap
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"sync"
     7  	"strconv"
     8  )
     9  
    10  // TODO SearchPathMap 에서 사용하기 위해 생성 (현재는 생성만)
    11  // 테스트 필요.
    12  type IntSet struct {
    13  	table      []*IntSetry
    14  	count      int
    15  	threshold  int
    16  	loadFactor float32
    17  	lock       sync.Mutex
    18  	max        int
    19  }
    20  
    21  func NewIntSet() *IntSet {
    22  
    23  	initCapacity := DEFAULT_CAPACITY
    24  	loadFactor := DEFAULT_LOAD_FACTOR
    25  
    26  	this := new(IntSet)
    27  	this.loadFactor = float32(loadFactor)
    28  	this.table = make([]*IntSetry, initCapacity)
    29  	this.threshold = int(float64(initCapacity) * loadFactor)
    30  	return this
    31  }
    32  
    33  func NewIntSetArray(arr []string) *IntSet {
    34  
    35  	initCapacity := DEFAULT_CAPACITY
    36  	loadFactor := DEFAULT_LOAD_FACTOR
    37  
    38  	this := new(IntSet)
    39  	this.loadFactor = float32(loadFactor)
    40  	this.table = make([]*IntSetry, initCapacity)
    41  	this.threshold = int(float64(initCapacity) * loadFactor)
    42  	return this
    43  }
    44  
    45  func (this *IntSet) Size() int {
    46  	return this.count
    47  }
    48  
    49  func (this *IntSet) Values() *IntSetEnumer {
    50  	return &IntSetEnumer{table: this.table, index: len(this.table), entry: nil}
    51  }
    52  
    53  func (this *IntSet) Contains(key int32) bool {
    54  	this.lock.Lock()
    55  	defer this.lock.Unlock()
    56  	tab := this.table
    57  	index := uint(key) % uint(len(tab))
    58  	for e := tab[index]; e != nil; e = e.next {
    59  		if e.key == key {
    60  			return true
    61  		}
    62  	}
    63  	return false
    64  }
    65  
    66  func (this *IntSet) rehash() {
    67  	oldCapacity := len(this.table)
    68  	oldMap := this.table
    69  	newCapacity := oldCapacity*2 + 1
    70  	newMap := make([]*IntSetry, newCapacity)
    71  	this.threshold = int(float32(newCapacity) * this.loadFactor)
    72  	this.table = newMap
    73  	for i := oldCapacity; i > 0; i-- {
    74  		for old := oldMap[i-1]; old != nil; {
    75  			e := old
    76  			old = old.next
    77  			index := uint(e.key) % uint(newCapacity)
    78  			e.next = newMap[index]
    79  			newMap[index] = e
    80  		}
    81  	}
    82  }
    83  
    84  func (this *IntSet) PutAll(values []int32) {
    85  	if values == nil {
    86  		return
    87  	}
    88  	ln := len(values)
    89  	for i := 0; i < ln; i++ {
    90  		this.Put(values[i])
    91  	}
    92  }
    93  
    94  func (this *IntSet) Put(key int32) bool {
    95  	this.lock.Lock()
    96  	defer this.lock.Unlock()
    97  	return this.put(key)
    98  }
    99  
   100  func (this *IntSet) put(value int32) bool {
   101  	tab := this.table
   102  	index := uint(value) % uint(len(tab))
   103  	for e := tab[index]; e != nil; e = e.next {
   104  		if e.key == value {
   105  			return false
   106  		}
   107  	}
   108  	if this.count >= this.threshold {
   109  		this.rehash()
   110  		tab = this.table
   111  		index = uint(value) % uint(len(tab))
   112  	}
   113  	e := &IntSetry{key: value, next: tab[index]}
   114  	tab[index] = e
   115  	this.count++
   116  	return true
   117  }
   118  
   119  func (this *IntSet) Remove(key int32) int32 {
   120  	this.lock.Lock()
   121  	defer this.lock.Unlock()
   122  
   123  	return this.remove(key)
   124  }
   125  
   126  func (this *IntSet) remove(key int32) int32 {
   127  	tab := this.table
   128  	index := uint(key) % uint(len(tab))
   129  	e := tab[index]
   130  	var prev *IntSetry = nil
   131  	for e != nil {
   132  		if e.key == key {
   133  			if prev != nil {
   134  				prev.next = e.next
   135  			} else {
   136  				tab[index] = e.next
   137  			}
   138  			this.count--
   139  			return key
   140  		}
   141  		prev = e
   142  		e = e.next
   143  	}
   144  	return 0
   145  }
   146  
   147  func (this *IntSet) Clear() {
   148  	this.lock.Lock()
   149  	defer this.lock.Unlock()
   150  	this.clear()
   151  }
   152  func (this *IntSet) clear() {
   153  	tab := this.table
   154  	for index := len(tab) - 1; index >= 0; index-- {
   155  		tab[index] = nil
   156  	}
   157  	this.count = 0
   158  }
   159  
   160  func (this *IntSet) ToString() string {
   161  	this.lock.Lock()
   162  	defer this.lock.Unlock()
   163  	return this.toString()
   164  }
   165  
   166  func (this *IntSet) toString() string {
   167  	max := this.Size() - 1
   168  
   169  	var buf bytes.Buffer
   170  
   171  	it := this.Values()
   172  	buf.WriteString("{")
   173  
   174  	for i := 0; i <= max; i++ {
   175  		key := it.NextInt()
   176  		buf.WriteString(strconv.Itoa(int(key)))
   177  		
   178  		if i < max {
   179  			buf.WriteString(", ")
   180  		}
   181  	}
   182  
   183  	buf.WriteString("}")
   184  	return buf.String()
   185  }
   186  
   187  //public static IntEnumer emptyEnumer = new IntEnumer() {
   188  //		public int nextInt() {
   189  //			return 0;
   190  //		}
   191  //
   192  //		public boolean hasMoreElements() {
   193  //			return false;
   194  //		}
   195  //	};
   196  
   197  type IntSetEnumer struct {
   198  	table []*IntSetry
   199  	index int
   200  	entry *IntSetry
   201  }
   202  
   203  func NewIntSetEnumer(table []*IntSetry, index int) {
   204  	p := new(IntSetEnumer)
   205  	p.table = table
   206  	p.index = len(table)
   207  	p.entry = nil
   208  }
   209  func (this *IntSetEnumer) HasMoreElements() bool {
   210  	for this.entry == nil && this.index > 0 {
   211  		this.index--
   212  		this.entry = this.table[this.index]
   213  	}
   214  	return this.entry != nil
   215  }
   216  
   217  func (this *IntSetEnumer) NextInt() int32 {
   218  	for this.entry == nil && this.index > 0 {
   219  		this.index--
   220  		this.entry = this.table[this.index]
   221  	}
   222  	if this.entry != nil {
   223  		e := this.entry
   224  		this.entry = e.next
   225  		return e.key
   226  	}
   227  	//panic("no more next")
   228  	return 0
   229  }
   230  
   231  func IntSetMain() {
   232  	s := NewIntSet()
   233  	s.Put(111)
   234  	s.Put(2222)
   235  	s.Put(3333)
   236  	//	s.Sort(c func(k1, k2 string) bool)
   237  	fmt.Println(s)
   238  	//	s.Sort(false)
   239  	fmt.Println(s)
   240  }