func (dq *Deque) getValueAtIndex(value proto.Message, index int) error {
	key := getIndexKey(index)
	data, err := dq.tx.Get(key)
	if err == ErrNotFound {
		return ErrNotFound
	} else if err != nil {
		return errors.Wrap(err, "an error occurred during Get")
	}
	err = proto.Unmarshal(data, value)
	if err != nil {
		return errors.Wrap(err, "couldn't unmarshal the element in peek")
	}
	return nil
}
Returns the value at given index.
We don't call initialize here, since this method is only called in methods like
Push/Peek which call initialize themselves.
package storage
import (
	"github.com/golang/protobuf/proto"
	"github.com/pkg/errors"
	"github.com/cube2222/octosql"
)
const (
	defaultFirstFreeFrontSpot = 0
	defaultFirstFreeBackSpot  = 1
)
var (
	dequeValueKeyPrefix     = []byte("$value$")
	dequeFirstFreeFrontSpot = []byte("$first$")
	dequeFirstFreeBackSpot  = []byte("$last$")
	defaultValues           = map[string]int{
		string(dequeFirstFreeFrontSpot): defaultFirstFreeFrontSpot,
		string(dequeFirstFreeBackSpot):  defaultFirstFreeBackSpot,
	}
)
type Deque struct {
	tx StateTransaction
	initializedFront bool
	initializedBack  bool
	firstFreeFrontSpot int
	firstFreeBackSpot  int
}
type DequeIterator struct {
	it Iterator
}
func NewDeque(tx StateTransaction) *Deque {
	return &Deque{
		tx:                 tx,
		initializedFront:   false,
		initializedBack:    false,
		firstFreeFrontSpot: defaultFirstFreeFrontSpot,
		firstFreeBackSpot:  defaultFirstFreeBackSpot,
	}
}
func NewDequeIterator(it Iterator) *DequeIterator {
	return &DequeIterator{
		it: it,
	}
}
func (dq *Deque) PushFront(value proto.Message) error {
	if !dq.initializedFront {
		err := dq.initializeFront()
		if err != nil {
			return errors.Wrap(err, "failed to initialize in PushFront")
		}
	}
	data, err := proto.Marshal(value)
	if err != nil {
		return errors.Wrap(err, "couldn't serialize given value in PushFront")
	}
	byteKey := getIndexKey(dq.firstFreeFrontSpot)
	err = dq.tx.Set(byteKey, data)
	if err != nil {
		return errors.Wrap(err, "failed to set value in PushFront")
	}
	err = dq.decreaseFirstFreeFrontSpot()  
	if err != nil {
		return errors.Wrap(err, "failed to decrease first free front spot in PushFront")
	}
	return nil
}
func (dq *Deque) PushBack(value proto.Message) error {
	if !dq.initializedBack {
		err := dq.initializeBack()
		if err != nil {
			return errors.Wrap(err, "failed to initialize in PushBack")
		}
	}
	data, err := proto.Marshal(value)
	if err != nil {
		return errors.Wrap(err, "couldn't serialize given value in PushBack")
	}
	byteKey := getIndexKey(dq.firstFreeBackSpot)
	err = dq.tx.Set(byteKey, data)
	if err != nil {
		return errors.Wrap(err, "failed to set value in PushBack")
	}
	err = dq.increaseFirstFreeBackSpot()  
	if err != nil {
		return errors.Wrap(err, "failed to increase first free back spot in PushBack")
	}
	return nil
}
func (dq *Deque) PopFront(value proto.Message) error {
	err := dq.PeekFront(value)  
	if err == ErrNotFound {
		return ErrNotFound
	} else if err != nil {
		return errors.Wrap(err, "failed to read first element in PopFront")
	}
	key := getIndexKey(dq.firstFreeFrontSpot + 1)
	err = dq.tx.Delete(key)
	if err != nil {
		return errors.Wrap(err, "failed to delete first element in PopFront")
	}
	err = dq.increaseFirstFreeFrontSpot()  
	if err != nil {
		return errors.Wrap(err, "failed to modify first free front spot in PopFront")
	}
	return nil
}
func (dq *Deque) PopBack(value proto.Message) error {
	err := dq.PeekBack(value)  
	if err == ErrNotFound {
		return ErrNotFound
	} else if err != nil {
		return errors.Wrap(err, "failed to read last element in PopBack")
	}
	key := getIndexKey(dq.firstFreeBackSpot - 1)
	err = dq.tx.Delete(key)
	if err != nil {
		return errors.Wrap(err, "failed to delete last element in PopBack")
	}
	err = dq.decreaseFirstFreeBackSpot()  
	if err != nil {
		return errors.Wrap(err, "failed to modify first free back spot in PopBack")
	}
	return nil
}
func (dq *Deque) PeekFront(value proto.Message) error {
	if !dq.initializedFront {
		err := dq.initializeFront()
		if err != nil {
			return errors.Wrap(err, "failed to initialize in PeekFront")
		}
	}
	return dq.getValueAtIndex(value, dq.firstFreeFrontSpot+1)
}
func (dq *Deque) PeekBack(value proto.Message) error {
	if !dq.initializedBack {
		err := dq.initializeBack()
		if err != nil {
			return errors.Wrap(err, "failed to initialize in PeekBack")
		}
	}
	return dq.getValueAtIndex(value, dq.firstFreeBackSpot-1)
}