func (o *PooledObject) StartEvictionTest() bool {
	o.lock.Lock()
	defer o.lock.Unlock()
	if o.state == StateIdle {
		o.state = StateEviction
		return true
	}
	return false
}
StartEvictionTest attempt to place the pooled object in the EVICTION state
package pool
import (
	"fmt"
	"sync"
	"time"
	"github.com/jolestar/go-commons-pool/v2/collections"
)
type PooledObjectState int
const (
	StateIdle PooledObjectState = iota
	StateAllocated
	StateEviction
	StateEvictionReturnToHead
	StateInvalid
	StateAbandoned
	StateReturning
)
type TrackedUse interface {
	GetLastUsed() time.Time
}
type PooledObject struct {
	Object         interface{}
	CreateTime     time.Time
	LastBorrowTime time.Time
	LastReturnTime time.Time
	LastUseTime   time.Time
	state         PooledObjectState
	BorrowedCount int32
	lock          sync.Mutex
}
func NewPooledObject(object interface{}) *PooledObject {
	time := time.Now()
	return &PooledObject{Object: object, state: StateIdle, CreateTime: time, LastUseTime: time, LastBorrowTime: time, LastReturnTime: time}
}
func (o *PooledObject) GetActiveTime() time.Duration {
	rTime := o.LastReturnTime
	bTime := o.LastBorrowTime
	if rTime.After(bTime) {
		return rTime.Sub(bTime)
	}
	return time.Since(bTime)
}
func (o *PooledObject) GetIdleTime() time.Duration {
	elapsed := time.Since(o.LastReturnTime)
	if elapsed >= 0 {
		return elapsed
	}
	return 0
}
func (o *PooledObject) GetLastUsedTime() time.Time {
	trackedUse, ok := o.Object.(TrackedUse)
	if ok && trackedUse.GetLastUsed().After(o.LastUseTime) {
		return trackedUse.GetLastUsed()
	}
	return o.LastUseTime
}
func (o *PooledObject) doAllocate() bool {
	if o.state == StateIdle {
		o.state = StateAllocated
		o.LastBorrowTime = time.Now()
		o.LastUseTime = o.LastBorrowTime
		o.BorrowedCount++
		return true
	} else if o.state == StateEviction {
		o.state = StateEvictionReturnToHead
		return false
	}
	return false
}
func (o *PooledObject) Allocate() bool {
	o.lock.Lock()
	result := o.doAllocate()
	o.lock.Unlock()
	return result
}
func (o *PooledObject) doDeallocate() bool {
	if o.state == StateAllocated ||
		o.state == StateReturning {
		o.state = StateIdle
		o.LastReturnTime = time.Now()
		return true
	}
	return false
}
func (o *PooledObject) Deallocate() bool {
	o.lock.Lock()
	result := o.doDeallocate()
	o.lock.Unlock()
	return result
}
func (o *PooledObject) Invalidate() {
	o.lock.Lock()
	o.invalidate()
	o.lock.Unlock()
}
func (o *PooledObject) invalidate() {
	o.state = StateInvalid
}
func (o *PooledObject) GetState() PooledObjectState {
	o.lock.Lock()
	defer o.lock.Unlock()
	return o.state
}
func (o *PooledObject) MarkAbandoned() {
	o.lock.Lock()
	o.markAbandoned()
	o.lock.Unlock()
}
func (o *PooledObject) markAbandoned() {
	o.state = StateAbandoned
}
func (o *PooledObject) MarkReturning() {
	o.lock.Lock()
	o.markReturning()
	o.lock.Unlock()
}
func (o *PooledObject) markReturning() {
	o.state = StateReturning
}