package  sftp 
 
import  ( 
	"sync"  
) 
 
type  allocator struct  { 
	sync .Mutex  
	available [][]byte  
	 
	used map [uint32 ][][]byte  
} 
 
func  newAllocator() *allocator  { 
	return  &allocator { 
		 
		available : make ([][]byte , 0 , SftpServerWorkerCount *2 ), 
		used :      make (map [uint32 ][][]byte ), 
	} 
} 
 
 
 
 
func  (a  *allocator ) GetPage (requestOrderID  uint32 ) []byte  { 
	a .Lock () 
	defer  a .Unlock () 
 
	var  result  []byte  
 
	 
	if  len (a .available ) > 0  { 
		truncLength  := len (a .available ) - 1  
		result  = a .available [truncLength ] 
 
		a .available [truncLength ] = nil            
		a .available  = a .available [:truncLength ]  
	} 
 
	 
	if  result  == nil  { 
		result  = make ([]byte , maxMsgLength ) 
	} 
 
	 
	a .used [requestOrderID ] = append (a .used [requestOrderID ], result ) 
 
	return  result  
} 
 
 
func  (a  *allocator ) ReleasePages (requestOrderID  uint32 ) { 
	a .Lock () 
	defer  a .Unlock () 
 
	if  used  := a .used [requestOrderID ]; len (used ) > 0  { 
		a .available  = append (a .available , used ...) 
	} 
	delete (a .used , requestOrderID ) 
} 
 
 
 
func  (a  *allocator ) Free () { 
	a .Lock () 
	defer  a .Unlock () 
 
	a .available  = nil  
	a .used  = make (map [uint32 ][][]byte ) 
} 
 
func  (a  *allocator ) countUsedPages () int  { 
	a .Lock () 
	defer  a .Unlock () 
 
	num  := 0  
	for  _ , p  := range  a .used  { 
		num  += len (p ) 
	} 
	return  num  
} 
 
func  (a  *allocator ) countAvailablePages () int  { 
	a .Lock () 
	defer  a .Unlock () 
 
	return  len (a .available ) 
} 
 
func  (a  *allocator ) isRequestOrderIDUsed (requestOrderID  uint32 ) bool  { 
	a .Lock () 
	defer  a .Unlock () 
 
	_ , ok  := a .used [requestOrderID ] 
	return  ok  
} 
  
The pages are generated with Golds   v0.6.7 . (GOOS=linux GOARCH=amd64)
Golds  is a Go 101  project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1  (reachable from the left QR code) to get the latest news of Golds .