mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 17:52:25 -05:00 
			
		
		
		
	
		
			
	
	
		
			57 lines
		
	
	
	
		
			1,005 B
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			57 lines
		
	
	
	
		
			1,005 B
		
	
	
	
		
			Go
		
	
	
	
	
	
|  | package mutexes | ||
|  | 
 | ||
|  | type hashmap struct { | ||
|  | 	m map[string]*rwmutex | ||
|  | 	n int | ||
|  | } | ||
|  | 
 | ||
|  | func (m *hashmap) init(cap int) { | ||
|  | 	m.m = make(map[string]*rwmutex, cap) | ||
|  | 	m.n = cap | ||
|  | } | ||
|  | 
 | ||
|  | func (m *hashmap) Get(key string) *rwmutex { return m.m[key] } | ||
|  | 
 | ||
|  | func (m *hashmap) Put(key string, mu *rwmutex) { | ||
|  | 	m.m[key] = mu | ||
|  | 	if n := len(m.m); n > m.n { | ||
|  | 		m.n = n | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func (m *hashmap) Delete(key string) { | ||
|  | 	delete(m.m, key) | ||
|  | } | ||
|  | 
 | ||
|  | func (m *hashmap) Compact() { | ||
|  | 	// Noop when hashmap size | ||
|  | 	// is too small to matter. | ||
|  | 	if m.n < 2048 { | ||
|  | 		return | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// Difference between maximum map | ||
|  | 	// size and the current map size. | ||
|  | 	diff := m.n - len(m.m) | ||
|  | 
 | ||
|  | 	// Maximum load factor before | ||
|  | 	// runtime allocates new hmap: | ||
|  | 	// maxLoad = 13 / 16 | ||
|  | 	// | ||
|  | 	// So we apply the inverse/2, once | ||
|  | 	// $maxLoad/2 % of hmap is empty we | ||
|  | 	// compact the map to drop buckets. | ||
|  | 	if 2*16*diff > m.n*13 { | ||
|  | 
 | ||
|  | 		// Create new map only as big as required. | ||
|  | 		m2 := make(map[string]*rwmutex, len(m.m)) | ||
|  | 		for k, v := range m.m { | ||
|  | 			m2[k] = v | ||
|  | 		} | ||
|  | 
 | ||
|  | 		// Set new. | ||
|  | 		m.m = m2 | ||
|  | 		m.n = len(m2) | ||
|  | 	} | ||
|  | } |