2014-12-05 21:45:49 +01:00
package restic
2014-11-23 16:48:00 +01:00
2015-02-08 13:40:11 +01:00
import (
2015-02-09 23:38:50 +01:00
"crypto/sha256"
2015-02-08 13:40:11 +01:00
"sync"
2014-11-23 16:48:00 +01:00
2015-02-09 23:38:50 +01:00
"github.com/restic/restic/chunker"
2015-02-08 13:40:11 +01:00
"github.com/restic/restic/debug"
2014-11-23 16:48:00 +01:00
)
2015-02-08 13:40:11 +01:00
type poolStats struct {
m sync . Mutex
mget map [ string ] int
mput map [ string ] int
mmax map [ string ] int
2015-02-09 23:38:50 +01:00
new int
2015-02-08 13:40:11 +01:00
get int
put int
max int
2014-11-23 16:48:00 +01:00
}
2015-02-08 13:40:11 +01: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 16:48:00 +01:00
2015-02-08 13:40:11 +01:00
s . mget [ k ] ++
cur = s . mget [ k ] - s . mput [ k ]
if cur > s . mmax [ k ] {
s . mmax [ k ] = cur
}
}
2014-11-23 16:48:00 +01:00
}
2015-02-08 13:40:11 +01:00
func ( s * poolStats ) Put ( k string ) {
s . m . Lock ( )
defer s . m . Unlock ( )
2014-11-23 16:48:00 +01:00
2015-02-08 13:40:11 +01: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 23:38:50 +01:00
chunkPool = sync . Pool { New : newChunkBuf }
chunkerPool = sync . Pool { New : newChunker }
2015-02-08 13:40:11 +01:00
2015-02-09 23:38:50 +01:00
chunkStats = newPoolStats ( )
nodeStats = newPoolStats ( )
chunkerStats = newPoolStats ( )
2015-02-08 13:40:11 +01:00
)
func newChunkBuf ( ) interface { } {
2015-02-09 23:38:50 +01:00
chunkStats . m . Lock ( )
defer chunkStats . m . Unlock ( )
chunkStats . new ++
2015-03-14 19:53:51 +01:00
// create buffer for iv, data and mac
2014-11-23 22:58:28 +01:00
return make ( [ ] byte , maxCiphertextSize )
2014-11-23 16:48:00 +01:00
}
2015-02-09 23:38:50 +01:00
func newChunker ( ) interface { } {
chunkStats . m . Lock ( )
defer chunkStats . m . Unlock ( )
chunkStats . new ++
// create a new chunker with a nil reader
2015-02-11 13:10:36 +01:00
return chunker . New ( nil , chunkerBufSize , sha256 . New ( ) )
2015-02-09 23:38:50 +01:00
}
2014-11-23 16:48:00 +01:00
func GetChunkBuf ( s string ) [ ] byte {
2015-02-08 13:40:11 +01:00
chunkStats . Get ( s )
2014-11-23 16:48:00 +01:00
return chunkPool . Get ( ) . ( [ ] byte )
}
func FreeChunkBuf ( s string , buf [ ] byte ) {
2015-02-08 13:40:11 +01:00
chunkStats . Put ( s )
2014-11-23 16:48:00 +01:00
chunkPool . Put ( buf )
}
2015-02-09 23:38:50 +01: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 16:48:00 +01:00
func PoolAlloc ( ) {
2015-02-09 23:38:50 +01: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 13:40:11 +01:00
for k , v := range chunkStats . mget {
2015-02-09 23:38:50 +01: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 13:40:11 +01:00
}
2014-11-23 16:48:00 +01:00
2015-02-09 23:38:50 +01: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 13:40:11 +01: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 23:38:50 +01: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 16:48:00 +01:00
}