package utils

import (
	"sync"
	//"strconv"
)

//////////////////////////////////////////////////////////

type SvStore struct {
	sync.Mutex
	m map[string]interface{}
}

func NewSvStore() *SvStore {
	return &SvStore{
		m: make(map[string]interface{}),
	}
}

func (self *SvStore) Save(k string, v interface{}) error {
	self.Lock()

	var err error
	if _, ok := self.m[k]; ok {
		err = ErrAlreadyExists
	}
	self.m[k] = v

	self.Unlock()

	return err
}

func (self *SvStore) Get(k string) (interface{}, error) {
	self.Lock()
	defer self.Unlock()

	v, ok := self.m[k]
	if ok {
		return v, nil
	}
	return nil, ErrKeyNotExists
}

func (self *SvStore) Remove(k string) error {
	self.Lock()
	defer self.Unlock()

	_, ok := self.m[k]
	if !ok {
		return ErrKeyNotExists
	}
	delete(self.m, k)

	return nil
}

//////////////////////////////////////////////////////////////

type NvStore struct {
	sync.Mutex
	m map[uint64]interface{}
}

func NewNvStore() *NvStore {
	return &NvStore{
		m: make(map[uint64]interface{}),
	}
}

func (self *NvStore) Save(k uint64, v interface{}) error {
	self.Lock()

	var err error
	if _, ok := self.m[k]; ok {
		err = ErrAlreadyExists
	}
	self.m[k] = v

	self.Unlock()

	return err
}

func (self *NvStore) Get(k uint64) (interface{}, error) {
	self.Lock()
	defer self.Unlock()

	v, ok := self.m[k]
	if ok {
		return v, nil
	}
	return nil, ErrKeyNotExists
}

func (self *NvStore) Peek(k uint64) (interface{}, error) {
	self.Lock()
	defer self.Unlock()

	v, ok := self.m[k]
	if ok {
		delete(self.m, k)
		return v, nil
	}
	return nil, ErrKeyNotExists
}

func (self *NvStore) Remove(k uint64) error {
	self.Lock()
	defer self.Unlock()

	_, ok := self.m[k]
	if !ok {
		return ErrKeyNotExists
	}
	delete(self.m, k)

	return nil
}

func (self *NvStore) Num() int {
	self.Lock()
	num := len(self.m)
	self.Unlock()
	return num
}
