mirror of
https://github.com/pgsty/minio.git
synced 2026-07-23 22:16:15 +03:00
XL: Implement ListObjects channel and pool management.
This commit is contained in:
committed by
Harshavardhana
parent
70a1231f02
commit
1cf1532ca3
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Minio Cloud Storage, (C) 2016 Minio, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Global lookup timeout.
|
||||
const (
|
||||
globalLookupTimeout = time.Minute * 30 // 30minutes.
|
||||
)
|
||||
|
||||
// treeWalkerPoolInfo - tree walker pool info carries temporary walker
|
||||
// channel stored until timeout is called.
|
||||
type treeWalkerPoolInfo struct {
|
||||
treeWalkerCh chan treeWalker
|
||||
treeWalkerDoneCh chan struct{}
|
||||
doneCh chan<- struct{}
|
||||
}
|
||||
|
||||
// treeWalkerPool - tree walker pool is a set of temporary tree walker
|
||||
// objects. Any item stored in the pool will be removed automatically at
|
||||
// a given timeOut value. This pool is safe for use by multiple
|
||||
// goroutines simultaneously. pool's purpose is to cache tree walker
|
||||
// channels for later reuse.
|
||||
type treeWalkerPool struct {
|
||||
pool map[listParams][]treeWalkerPoolInfo
|
||||
timeOut time.Duration
|
||||
lock *sync.Mutex
|
||||
}
|
||||
|
||||
// newTreeWalkerPool - initialize new tree walker pool.
|
||||
func newTreeWalkerPool(timeout time.Duration) *treeWalkerPool {
|
||||
tPool := &treeWalkerPool{
|
||||
pool: make(map[listParams][]treeWalkerPoolInfo),
|
||||
timeOut: timeout,
|
||||
lock: &sync.Mutex{},
|
||||
}
|
||||
return tPool
|
||||
}
|
||||
|
||||
// Release - selects an item from the pool based on the input
|
||||
// listParams, removes it from the pool, and returns treeWalker
|
||||
// channels. Release will return nil, if listParams is not
|
||||
// recognized.
|
||||
func (t treeWalkerPool) Release(params listParams) (treeWalkerCh chan treeWalker, treeWalkerDoneCh chan struct{}) {
|
||||
t.lock.Lock()
|
||||
defer t.lock.Unlock()
|
||||
treeWalk, ok := t.pool[params]
|
||||
if ok {
|
||||
if len(treeWalk) > 0 {
|
||||
treeWalker := treeWalk[0]
|
||||
if len(treeWalk[1:]) > 0 {
|
||||
t.pool[params] = treeWalk[1:]
|
||||
} else {
|
||||
delete(t.pool, params)
|
||||
}
|
||||
treeWalker.doneCh <- struct{}{}
|
||||
return treeWalker.treeWalkerCh, treeWalker.treeWalkerDoneCh
|
||||
}
|
||||
}
|
||||
// Release return nil if params not found.
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Set - adds new list params along with treeWalker channel to the
|
||||
// pool for future. Additionally this also starts a go routine which
|
||||
// waits at the configured timeout. Additionally this go-routine is
|
||||
// also closed pro-actively by 'Release' call when the treeWalker
|
||||
// item is obtained from the pool.
|
||||
func (t treeWalkerPool) Set(params listParams, treeWalkerCh chan treeWalker, treeWalkerDoneCh chan struct{}) {
|
||||
t.lock.Lock()
|
||||
defer t.lock.Unlock()
|
||||
|
||||
var treeWalkerIdx = len(t.pool[params])
|
||||
var doneCh = make(chan struct{})
|
||||
t.pool[params] = append(t.pool[params], treeWalkerPoolInfo{
|
||||
treeWalkerCh: treeWalkerCh,
|
||||
treeWalkerDoneCh: treeWalkerDoneCh,
|
||||
doneCh: doneCh,
|
||||
})
|
||||
|
||||
// Safe expiry of treeWalkerCh after timeout.
|
||||
go func(doneCh <-chan struct{}) {
|
||||
select {
|
||||
// Wait until timeOut
|
||||
case <-time.After(t.timeOut):
|
||||
t.lock.Lock()
|
||||
treeWalk := t.pool[params]
|
||||
treeWalk = append(treeWalk[:treeWalkerIdx], treeWalk[treeWalkerIdx+1:]...)
|
||||
if len(treeWalk) == 0 {
|
||||
delete(t.pool, params)
|
||||
} else {
|
||||
t.pool[params] = treeWalk
|
||||
}
|
||||
close(treeWalkerDoneCh)
|
||||
t.lock.Unlock()
|
||||
case <-doneCh:
|
||||
return
|
||||
}
|
||||
}(doneCh)
|
||||
}
|
||||
Reference in New Issue
Block a user