func (dm *DMap) PutEx(key string, value interface{}, timeout time.Duration) error {
	err := dm.dm.PutEx(key, value, timeout)
	return convertDMapError(err)
}
PutEx sets the value for the given key with TTL. It overwrites any previous
value for that key. It's thread-safe. The key has to be string. value type
is arbitrary. It is safe to modify the contents of the arguments after
Put returns but not before.
package olric
import (
	"errors"
	"time"
	"github.com/buraksezer/olric/internal/dmap"
	"github.com/buraksezer/olric/query"
)
const (
	IfNotFound = int16(1) << iota
	IfFound
)
var (
	ErrKeyNotFound = errors.New("key not found")
	ErrKeyFound = errors.New("key found")
	ErrWriteQuorum = errors.New("write quorum cannot be reached")
	ErrReadQuorum = errors.New("read quorum cannot be reached")
	ErrLockNotAcquired = errors.New("lock not acquired")
	ErrNoSuchLock = errors.New("no such lock")
	ErrEndOfQuery = errors.New("end of query")
	ErrClusterQuorum = errors.New("cannot be reached cluster quorum to operate")
	ErrKeyTooLarge = errors.New("key too large")
)
const NumConcurrentWorkers = 2
type QueryResponse map[string]interface{}
func convertDMapError(err error) error {
	switch {
	case errors.Is(err, dmap.ErrKeyFound):
		return ErrKeyFound
	case errors.Is(err, dmap.ErrKeyNotFound):
		return ErrKeyNotFound
	case errors.Is(err, dmap.ErrDMapNotFound):
		return ErrKeyNotFound
	case errors.Is(err, dmap.ErrEndOfQuery):
		return ErrEndOfQuery
	case errors.Is(err, dmap.ErrLockNotAcquired):
		return ErrLockNotAcquired
	case errors.Is(err, dmap.ErrNoSuchLock):
		return ErrNoSuchLock
	case errors.Is(err, dmap.ErrReadQuorum):
		return ErrReadQuorum
	case errors.Is(err, dmap.ErrWriteQuorum):
		return ErrWriteQuorum
	case errors.Is(err, dmap.ErrServerGone):
		return ErrServerGone
	default:
		return convertClusterError(err)
	}
}
type Entry struct {
	Key       string
	Value     interface{}
	TTL       int64
	Timestamp int64
}
type LockContext struct {
	ctx *dmap.LockContext
}
type Cursor struct {
	cursor *dmap.Cursor
}
type DMap struct {
	dm *dmap.DMap
}
func (db *Olric) NewDMap(name string) (*DMap, error) {
	dm, err := db.dmap.NewDMap(name)
	if err != nil {
		return nil, convertDMapError(err)
	}
	return &DMap{
		dm: dm,
	}, nil
}
func (dm *DMap) Name() string {
	return dm.dm.Name()
}
func (dm *DMap) Get(key string) (interface{}, error) {
	value, err := dm.dm.Get(key)
	if err != nil {
		return nil, convertDMapError(err)
	}
	return value, nil
}
func (dm *DMap) GetEntry(key string) (*Entry, error) {
	e, err := dm.dm.GetEntry(key)
	if err != nil {
		return nil, convertDMapError(err)
	}
	return &Entry{
		Key:       e.Key,
		Value:     e.Value,
		TTL:       e.TTL,
		Timestamp: e.Timestamp,
	}, nil
}
func (dm *DMap) LockWithTimeout(key string, timeout, deadline time.Duration) (*LockContext, error) {
	ctx, err := dm.dm.LockWithTimeout(key, timeout, deadline)
	if err != nil {
		return nil, convertDMapError(err)
	}
	return &LockContext{ctx: ctx}, nil
}
func (dm *DMap) Lock(key string, deadline time.Duration) (*LockContext, error) {
	ctx, err := dm.dm.Lock(key, deadline)
	if err != nil {
		return nil, convertDMapError(err)
	}
	return &LockContext{ctx: ctx}, nil
}
func (l *LockContext) Unlock() error {
	err := l.ctx.Unlock()
	return convertDMapError(err)
}