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

     1  package hmap
     2  
     3  import (
     4  	"fmt"
     5  	//"log"
     6  	"math"
     7  	"sync"
     8  
     9  	"github.com/whatap/golib/util/stringutil"
    10  )
    11  
    12  type IntKeyMap struct {
    13  	// []*IntKeyEntry
    14  	table []*IntKeyEntry
    15  	// int
    16  	count int
    17  	// int
    18  	threshold int
    19  	// float32
    20  	loadFactor float32
    21  	// sync.Mutex
    22  	lock sync.Mutex
    23  
    24  	// create func(int32) interface{]// create, intern 함수 사용 안함
    25  	//Create func(int32) interface{}
    26  }
    27  
    28  func NewIntKeyMapDefault() *IntKeyMap {
    29  
    30  	p := NewIntKeyMap(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR)
    31  
    32  	return p
    33  }
    34  
    35  func NewIntKeyMap(initCapacity int, loadFactor float32) *IntKeyMap {
    36  	defer func() {
    37  		if r := recover(); r != nil {
    38  			// TODO 추후 hmap 에서 recover 는 없애고 panic 처리. 호출하는 쪽에서 recover 할 것
    39  			//logutil.Println("WA823", "Recover:",r)
    40  			//return NewIntKeyMap(DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR)
    41  		}
    42  	}()
    43  
    44  	p := new(IntKeyMap)
    45  
    46  	if initCapacity < 0 {
    47  		panic(fmt.Sprintf("Capacity Error: %d", initCapacity))
    48  		//throw new RuntimeException("Capacity Error: " + initCapacity);
    49  	}
    50  	if loadFactor <= 0 {
    51  		panic(fmt.Sprintf("Load Count Error: %f", loadFactor))
    52  		//throw new RuntimeException("Load Count Error: " + loadFactor);
    53  	}
    54  	if initCapacity == 0 {
    55  		initCapacity = 1
    56  	}
    57  	p.loadFactor = loadFactor
    58  	p.table = make([]*IntKeyEntry, initCapacity)
    59  	p.threshold = int(float32(initCapacity) * loadFactor)
    60  
    61  	return p
    62  }
    63  
    64  func (this *IntKeyMap) Size() int {
    65  	return this.count
    66  }
    67  
    68  func (this *IntKeyMap) Keys() IntEnumer {
    69  	this.lock.Lock()
    70  	defer this.lock.Unlock()
    71  
    72  	return NewIntKeyEnumer(ELEMENT_TYPE_KEYS, this.table)
    73  }
    74  
    75  func (this *IntKeyMap) Values() Enumeration {
    76  	//public synchronized Enumeration<V> values() {
    77  	this.lock.Lock()
    78  	defer this.lock.Unlock()
    79  	return NewIntKeyEnumer(ELEMENT_TYPE_VALUES, this.table)
    80  }
    81  
    82  func (this *IntKeyMap) Entries() Enumeration {
    83  	//public synchronized Enumeration<IntKeyEntry<V>> entries() {
    84  	this.lock.Lock()
    85  	defer this.lock.Unlock()
    86  	return NewIntKeyEnumer(ELEMENT_TYPE_ENTRIES, this.table)
    87  }
    88  
    89  func (this *IntKeyMap) ContainsValue(value interface{}) bool {
    90  	//public synchronized boolean containsValue(V value) {
    91  	this.lock.Lock()
    92  	defer this.lock.Unlock()
    93  	if value == nil {
    94  		return false
    95  	}
    96  
    97  	// TODO
    98  	//IntKeyEntry<V> tab[] = this.table;
    99  	//		tab := this.table
   100  	//		i := len(tab)
   101  	//		for i> 0 ; i-- {
   102  	//			//for (IntKeyEntry<V> e = tab[i]; e != null; e = e.next) {
   103  	//			for e := tab[i]; e != nil; e = e.Next() {
   104  	//				if CompareUtil.equals(e.value, value) {
   105  	//					return true
   106  	//				}
   107  	//			}
   108  	//		}
   109  	return false
   110  }
   111  
   112  func (this *IntKeyMap) ContainsKey(key int32) bool {
   113  	this.lock.Lock()
   114  	defer this.lock.Unlock()
   115  
   116  	tab := this.table
   117  	index := int(this.hash(key)) % len(tab)
   118  
   119  	//for (IntKeyEntry<V> e = tab[index]; e != null; e = e.next) {
   120  	for e := tab[index]; e != nil; e = e.Next {
   121  		if e.Key == key {
   122  			return true
   123  		}
   124  	}
   125  	return false
   126  }
   127  
   128  func (this *IntKeyMap) hash(h int32) uint {
   129  	ret := uint(h)
   130  	// TODO
   131  	ret ^= (uint(h) >> 20) ^ (uint(h) >> 12)
   132  	ret = ret ^ (uint(h) >> 7) ^ (uint(h) >> 4)
   133  
   134  	return ret & uint(math.MaxInt32)
   135  }
   136  
   137  func (this *IntKeyMap) Get(key int32) interface{} {
   138  	this.lock.Lock()
   139  	defer this.lock.Unlock()
   140  
   141  	tab := this.table
   142  	index := int(this.hash(key)) % len(tab)
   143  
   144  	//for (IntKeyEntry<V> e = tab[index]; e != null; e = e.next) {
   145  	for e := tab[index]; e != nil; e = e.Next {
   146  		if e.Key == key {
   147  			return e.Value
   148  		}
   149  	}
   150  	return nil
   151  }
   152  
   153  func (this *IntKeyMap) rehash() {
   154  	oldCapacity := len(this.table)
   155  	oldMap := this.table
   156  	newCapacity := oldCapacity*2 + 1
   157  
   158  	newMap := make([]*IntKeyEntry, newCapacity)
   159  	this.threshold = int(float32(newCapacity) * this.loadFactor)
   160  	this.table = newMap
   161  
   162  	for i := oldCapacity; i > 0; i-- {
   163  		for old := oldMap[i-1]; old != nil; {
   164  			e := old
   165  			old = old.Next
   166  			index := int(this.hash(e.Key)) % newCapacity
   167  			e.Next = newMap[index]
   168  			newMap[index] = e
   169  		}
   170  	}
   171  }
   172  
   173  func (this *IntKeyMap) KeyArray() []int32 {
   174  	this.lock.Lock()
   175  	defer this.lock.Unlock()
   176  
   177  	_keys := make([]int32, this.Size())
   178  
   179  	//IntEnumer en = this.keys();
   180  	en := this.Keys()
   181  
   182  	for i := 0; i < len(_keys); i++ {
   183  		_keys[i] = en.NextInt()
   184  	}
   185  	return _keys
   186  }
   187  
   188  func (this *IntKeyMap) Put(key int32, value interface{}) interface{} {
   189  	this.lock.Lock()
   190  	defer this.lock.Unlock()
   191  
   192  	tab := this.table
   193  	_hash := this.hash(key)
   194  	index := _hash % uint(len(tab))
   195  
   196  	e := tab[index]
   197  	for e = tab[index]; e != nil; e = e.Next {
   198  		if e.Key == key {
   199  			old := e.Value
   200  			e.Value = value
   201  			return old
   202  		}
   203  	}
   204  
   205  	if this.count >= this.threshold {
   206  		this.rehash()
   207  		tab = this.table
   208  		index = _hash % uint(len(tab))
   209  	}
   210  	e = NewIntKeyEntry(key, value, tab[index])
   211  	tab[index] = e
   212  	this.count++
   213  
   214  	return nil
   215  }
   216  
   217  //  intern 함수 사용 안함
   218  //func (this *IntKeyMap) Intern(key int32) interface{} {
   219  //	this.lock.Lock()
   220  //	defer this.lock.Unlock()
   221  //	tab := this.table
   222  //	_hash := this.hash(key)
   223  //	index := _hash % uint(len(tab))
   224  //
   225  //	for e := tab[index]; e != nil; e = e.Next {
   226  //		if e.Key == key {
   227  //			return e.Value
   228  //		}
   229  //	}
   230  //
   231  //	//var value interface{}
   232  //	value := this.create(key)
   233  //
   234  //	if value == nil {
   235  //		return nil
   236  //	}
   237  //
   238  //	if this.count >= this.threshold {
   239  //		this.rehash()
   240  //		tab = this.table
   241  //		index = _hash % uint(len(tab))
   242  //	}
   243  //	e := NewIntKeyEntry(key, value, tab[index])
   244  //	tab[index] = e
   245  //	this.count++
   246  //	return value
   247  //}
   248  
   249  //Override create , intern 함수 사용 안함
   250  //func (this *IntKeyMap) create(key int32) interface{} {
   251  //	if this.Create == nil {
   252  //		panic("Error IntKeyMap.Count is nil")
   253  //	}
   254  //
   255  //	return this.Create(key)
   256  //	//throw new RuntimeException("not implemented create()")
   257  //	//return interface{}
   258  //	//return nil
   259  //}
   260  
   261  func (this *IntKeyMap) Remove(key int32) interface{} {
   262  	this.lock.Lock()
   263  	defer this.lock.Unlock()
   264  
   265  	tab := this.table
   266  	index := this.hash(key) % uint(len(tab))
   267  	var prev *IntKeyEntry
   268  	prev = nil
   269  	//for e := tab[index], prev := nil; e != nil; prev = e, e = e.Next) {
   270  	for e := tab[index]; e != nil; {
   271  		if e.Key == key {
   272  			if prev != nil {
   273  				prev.Next = e.Next
   274  			} else {
   275  				tab[index] = e.Next
   276  			}
   277  			this.count--
   278  			oldValue := e.Value
   279  			e.Value = nil
   280  			return oldValue
   281  		}
   282  
   283  		prev = e
   284  		e = e.Next
   285  	}
   286  	return nil
   287  }
   288  
   289  func (this *IntKeyMap) Clear() {
   290  	this.lock.Lock()
   291  	defer this.lock.Unlock()
   292  	tab := this.table
   293  
   294  	for index := len(tab) - 1; index >= 0; index-- {
   295  		tab[index] = nil
   296  	}
   297  	this.count = 0
   298  
   299  }
   300  
   301  func (this *IntKeyMap) ToString() string {
   302  	buf := stringutil.NewStringBuffer()
   303  
   304  	it := this.Entries()
   305  	buf.Append("{")
   306  
   307  	for i := 0; it.HasMoreElements(); i++ {
   308  		e := it.NextElement().(*IntKeyEntry)
   309  
   310  		if i > 0 {
   311  			buf.Append(", ")
   312  		}
   313  		buf.Append(e.ToString())
   314  	}
   315  	buf.Append("}")
   316  
   317  	return buf.ToString()
   318  }
   319  
   320  func (this *IntKeyMap) ToFormatString() string {
   321  	buf := stringutil.NewStringBuffer()
   322  
   323  	it := this.Entries()
   324  	buf.Append("{\n")
   325  	for it.HasMoreElements() {
   326  		e := it.NextElement().(*IntKeyEntry)
   327  		buf.Append("\t").Append(e.ToString()).Append("\n")
   328  	}
   329  	buf.Append("}")
   330  	return buf.ToString()
   331  }
   332  
   333  func (this *IntKeyMap) PutAll(other *IntKeyMap) {
   334  	if other == nil {
   335  		return
   336  	}
   337  	it := other.Entries()
   338  
   339  	for it.HasMoreElements() {
   340  		e := it.NextElement().(*IntKeyEntry)
   341  		this.Put(e.GetKey(), e.GetValue())
   342  	}
   343  }
   344  
   345  type IntKeyEnumer struct {
   346  	table        []*IntKeyEntry
   347  	entry        *IntKeyEntry
   348  	index        int
   349  	lastReturned *IntKeyEntry
   350  	Type         int
   351  }
   352  
   353  func NewIntKeyEnumer(Type int, table []*IntKeyEntry) *IntKeyEnumer {
   354  	p := new(IntKeyEnumer)
   355  	p.table = table
   356  	p.index = len(table)
   357  	p.entry = nil
   358  	p.lastReturned = nil
   359  	p.Type = Type
   360  	return p
   361  }
   362  
   363  func (this *IntKeyEnumer) HasMoreElements() bool {
   364  	for this.entry == nil && this.index > 0 {
   365  		this.index--
   366  		this.entry = this.table[this.index]
   367  	}
   368  	//fmt.Println("IntKeyMap.IntKeyEnumer HasMoreElements index=", this.index, ",return =", (this.entry != nil))
   369  	return (this.entry != nil)
   370  }
   371  
   372  func (this *IntKeyEnumer) NextElement() interface{} {
   373  	//fmt.Println("IntKeyMap.IntKeyEnumer NextElement index=", this.index, ",entry =", this.entry)
   374  
   375  	for this.entry == nil && this.index > 0 {
   376  		this.index--
   377  		this.entry = this.table[this.index]
   378  	}
   379  
   380  	if this.entry != nil {
   381  		//fmt.Println("IntKeyMap.IntKeyEnumer NextElement this.entry != nil , index=", this.index, ",entry =", this.entry)
   382  		this.lastReturned = this.entry
   383  		e := this.lastReturned
   384  
   385  		this.entry = e.Next
   386  
   387  		switch this.Type {
   388  		case ELEMENT_TYPE_KEYS:
   389  			return e.Key
   390  		case ELEMENT_TYPE_VALUES:
   391  			return e.Value
   392  		default:
   393  			return e
   394  		}
   395  	}
   396  	//fmt.Println("IntKeyMap.IntKeyEnumer NextElement for , index=", this.index, ",entry =", this.entry)
   397  
   398  	//throw new NoSuchElementException("no more next");
   399  	panic("Panic NextElement no more next")
   400  
   401  }
   402  
   403  func (this *IntKeyEnumer) NextInt() int32 {
   404  	for this.entry == nil && this.index > 0 {
   405  		this.index--
   406  		this.entry = this.table[this.index]
   407  	}
   408  
   409  	if this.entry != nil {
   410  		this.lastReturned = this.entry
   411  		e := this.lastReturned
   412  		this.entry = e.Next
   413  		return e.Key
   414  	}
   415  	//throw new NoSuchElementException("no more next");
   416  	panic("Panic NextInt no more next")
   417  
   418  }