2014-12-05 20:45:49 +00:00
package restic
2014-11-23 15:48:00 +00:00
2015-02-08 12:40:11 +00:00
import (
2015-02-09 22:38:50 +00:00
"crypto/sha256"
2015-02-08 12:40:11 +00:00
"sync"
2014-11-23 15:48:00 +00:00
2015-02-09 22:38:50 +00:00
"github.com/restic/restic/chunker"
2015-02-08 12:40:11 +00:00
"github.com/restic/restic/debug"
2014-11-23 15:48:00 +00:00
)
2015-02-08 12:40:11 +00:00
type poolStats struct {
m sync . Mutex
mget map [ string ] int
mput map [ string ] int
mmax map [ string ] int
2015-02-09 22:38:50 +00:00
new int
2015-02-08 12:40:11 +00:00
get int
put int
max int
2014-11-23 15:48:00 +00:00
}
2015-02-08 12:40:11 +00:00
func ( s * poolStats ) Get ( k string ) {
s . m . Lock ( )
defer s . m . Unlock ( )
s . get += 1
cur := s . get - s . put
if cur > s . max {
s . max = cur
}
if k != "" {
if _ , ok := s . mget [ k ] ; ! ok {
s . mget [ k ] = 0
s . mput [ k ] = 0
s . mmax [ k ] = 0
}
2014-11-23 15:48:00 +00:00
2015-02-08 12:40:11 +00:00
s . mget [ k ] ++
cur = s . mget [ k ] - s . mput [ k ]
if cur > s . mmax [ k ] {
s . mmax [ k ] = cur
}
}
2014-11-23 15:48:00 +00:00
}
2015-02-08 12:40:11 +00:00
func ( s * poolStats ) Put ( k string ) {
s . m . Lock ( )
defer s . m . Unlock ( )
2014-11-23 15:48:00 +00:00
2015-02-08 12:40:11 +00:00
s . put += 1
if k != "" {
s . mput [ k ] ++
}
}
func newPoolStats ( ) * poolStats {
return & poolStats {
mget : make ( map [ string ] int ) ,
mput : make ( map [ string ] int ) ,
mmax : make ( map [ string ] int ) ,
}
}
var (
2015-02-09 22:38:50 +00:00
chunkPool = sync . Pool { New : newChunkBuf }
nodePool = sync . Pool { New : newNode }
chunkerPool = sync . Pool { New : newChunker }
2015-02-08 12:40:11 +00:00
2015-02-09 22:38:50 +00:00
chunkStats = newPoolStats ( )
nodeStats = newPoolStats ( )
chunkerStats = newPoolStats ( )
2015-02-08 12:40:11 +00:00
)
func newChunkBuf ( ) interface { } {
2015-02-09 22:38:50 +00:00
chunkStats . m . Lock ( )
defer chunkStats . m . Unlock ( )
chunkStats . new ++
2015-03-14 18:53:51 +00:00
// create buffer for iv, data and mac
2014-11-23 21:58:28 +00:00
return make ( [ ] byte , maxCiphertextSize )
2014-11-23 15:48:00 +00:00
}
func newNode ( ) interface { } {
2015-02-09 22:38:50 +00:00
nodeStats . m . Lock ( )
defer nodeStats . m . Unlock ( )
nodeStats . new ++
2014-11-23 15:48:00 +00:00
// create buffer for iv, data and hmac
return new ( Node )
}
2015-02-09 22:38:50 +00:00
func newChunker ( ) interface { } {
chunkStats . m . Lock ( )
defer chunkStats . m . Unlock ( )
chunkStats . new ++
// create a new chunker with a nil reader
2015-02-11 12:10:36 +00:00
return chunker . New ( nil , chunkerBufSize , sha256 . New ( ) )
2015-02-09 22:38:50 +00:00
}
2014-11-23 15:48:00 +00:00
func GetChunkBuf ( s string ) [ ] byte {
2015-02-08 12:40:11 +00:00
chunkStats . Get ( s )
2014-11-23 15:48:00 +00:00
return chunkPool . Get ( ) . ( [ ] byte )
}
func FreeChunkBuf ( s string , buf [ ] byte ) {
2015-02-08 12:40:11 +00:00
chunkStats . Put ( s )
2014-11-23 15:48:00 +00:00
chunkPool . Put ( buf )
}
func GetNode ( ) * Node {
2015-02-08 12:40:11 +00:00
nodeStats . Get ( "" )
2014-11-23 15:48:00 +00:00
return nodePool . Get ( ) . ( * Node )
}
func FreeNode ( n * Node ) {
2015-02-08 12:40:11 +00:00
nodeStats . Put ( "" )
2014-11-23 15:48:00 +00:00
nodePool . Put ( n )
}
2015-02-09 22:38:50 +00:00
func GetChunker ( s string ) * chunker . Chunker {
chunkerStats . Get ( s )
return chunkerPool . Get ( ) . ( * chunker . Chunker )
}
func FreeChunker ( s string , ch * chunker . Chunker ) {
chunkerStats . Put ( s )
chunkerPool . Put ( ch )
}
2014-11-23 15:48:00 +00:00
func PoolAlloc ( ) {
2015-02-09 22:38:50 +00:00
debug . Log ( "pools.PoolAlloc" , "pool stats for chunk: new %d, get %d, put %d, diff %d, max %d\n" ,
chunkStats . new , chunkStats . get , chunkStats . put , chunkStats . get - chunkStats . put , chunkStats . max )
2015-02-08 12:40:11 +00:00
for k , v := range chunkStats . mget {
2015-02-09 22:38:50 +00:00
debug . Log ( "pools.PoolAlloc" , "pool stats for chunk[%s]: get %d, put %d, diff %d, max %d\n" ,
k , v , chunkStats . mput [ k ] , v - chunkStats . mput [ k ] , chunkStats . mmax [ k ] )
2015-02-08 12:40:11 +00:00
}
2014-11-23 15:48:00 +00:00
2015-02-09 22:38:50 +00:00
debug . Log ( "pools.PoolAlloc" , "pool stats for node: new %d, get %d, put %d, diff %d, max %d\n" ,
nodeStats . new , nodeStats . get , nodeStats . put , nodeStats . get - nodeStats . put , nodeStats . max )
2015-02-08 12:40:11 +00:00
for k , v := range nodeStats . mget {
debug . Log ( "pools.PoolAlloc" , "pool stats for node[%s]: get %d, put %d, diff %d, max %d\n" , k , v , nodeStats . mput [ k ] , v - nodeStats . mput [ k ] , nodeStats . mmax [ k ] )
}
2015-02-09 22:38:50 +00:00
debug . Log ( "pools.PoolAlloc" , "pool stats for chunker: new %d, get %d, put %d, diff %d, max %d\n" ,
chunkerStats . new , chunkerStats . get , chunkerStats . put , chunkerStats . get - chunkerStats . put , chunkerStats . max )
for k , v := range chunkerStats . mget {
debug . Log ( "pools.PoolAlloc" , "pool stats for chunker[%s]: get %d, put %d, diff %d, max %d\n" , k , v , chunkerStats . mput [ k ] , v - chunkerStats . mput [ k ] , chunkerStats . mmax [ k ] )
}
2014-11-23 15:48:00 +00:00
}