func (ll *LinkedList) GetNextFunc(val interface{}, mark *Item, equal func(a interface{}, b []byte) bool) (*Item, error) {
	_, _, empty, err := ll.first()
	if err != nil {
		return nil, err
	}
	if empty {
		return nil, fmt.Errorf("Empty list")
	}
	if val == nil {
		return nil, fmt.Errorf("Empty val")
	}
	if mark == nil {
		return nil, fmt.Errorf("Empty mark")
	}
	sd, ok := mark.Data.(*storedData)
	if !ok {
		return nil, fmt.Errorf("Invalid mark")
	}
	if ll != sd.internalLinkedList {
		return nil, fmt.Errorf("Invalid mark: item belongs to another linked list")
	}
	if equal == nil {
		return nil, fmt.Errorf("Empty comparing function")
	}
	var it *Item
	for k := mark; k != nil; k = k.Next() {
		if equal(val, k.Data.Value()) {
			it = k
			break
		}
	}
	return it, nil
}
GetNextFunc compares val with the value of every single node in the linked list,
starting from the next item of the element pointed to by mark, using the provided
function. If it finds that v and the value of some node are equal, according to
its criteria, then GetNextFunc returns the item containing the value of the
stored data.

If GetNextFunc can't find any matches, it returns an nil item and a nil error.

It returns either an "Empty val" error when called with a nil []byte val, an
"Empty mark" error when called with a nil beginning mark, an "Invalid mark" error when
the passed item is not a linked list item or belongs to another linked list, or an
"Empty comparing  function" error when called with a nil function to compare.

For an example on the usage, see example/linkedlist/main.go
package linkedlist
import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"log"
	"github.com/golang/protobuf/proto"
	"github.com/xyproto/simplebolt"
	pb "github.com/xyproto/simplebolt/linkedlist/nodes_pb"
	"go.etcd.io/bbolt"
)
type (
	boltBucket struct {
		db   *simplebolt.Database  
		name []byte                
	}
	LinkedList boltBucket
	storedData struct {
		key []byte
		value []byte
		internalLinkedList *LinkedList
	}
	Item struct {
		Data simplebolt.StoredData
	}
)
var (
	ErrBucketNotFound = errors.New("Bucket not found")
	ErrKeyNotFound = errors.New("Key not found")
	ErrDoesNotExist = errors.New("Does not exist")
	ErrExistsInSet = errors.New("Element already exists in set")
	ErrInvalidID = errors.New("Element ID can not contain \":\"")
	ErrFoundIt = errors.New("Found it")
	errReachedEnd = errors.New("Reached end of data structure")
)
func New(db *simplebolt.Database, id string) (*LinkedList, error) {
	name := []byte(id)
	if err := (*bbolt.DB)(db).Update(func(tx *bbolt.Tx) error {
		if _, err := tx.CreateBucketIfNotExists(name); err != nil {
			return errors.New("Could not create bucket: " + err.Error())
		}
		return nil
	}); err != nil {
		return nil, err
	}
	return &LinkedList{db, name}, nil
}
func (ll *LinkedList) PushBack(data []byte) error {
	if data == nil {
		return fmt.Errorf("Empty data")
	}
	return (*bbolt.DB)(ll.db).Update(func(tx *bbolt.Tx) error {
		bucket := tx.Bucket(ll.name)
		if bucket == nil {
			return ErrBucketNotFound
		}
		var (
			id        uint64
			err       error
			nodeBytes []byte
		)
		id, _ = bucket.NextSequence()
		newNodeID := byteID(id)
		newNode := &pb.LinkedListNode{
			Data: data,
			Next: nil,
			Prev: nil,
		}
		backKey := bucket.Get([]byte("BACK"))
		if backKey == nil {
			if nodeBytes, err = proto.Marshal(newNode); err != nil {
				return fmt.Errorf("Could not marshal. %v", err)
			}
			if err = bucket.Put(newNodeID, nodeBytes); err != nil {
				return fmt.Errorf("Could not save the first node. %v", err)
			}
			if err = bucket.Put([]byte("FRONT"), newNodeID); err != nil {
				return fmt.Errorf("Could not set front of the linked list. %v", err)
			}
			if err = bucket.Put([]byte("BACK"), newNodeID); err != nil {
				return fmt.Errorf("Could not set back of the linked list. %v", err)
			}
			return nil
		}
		nodeBytes = bucket.Get(backKey)
		if nodeBytes == nil {
			return ErrDoesNotExist
		}
		lastNode := &pb.LinkedListNode{}
		if err = proto.Unmarshal(nodeBytes, lastNode); err != nil {
			return fmt.Errorf("Could not unmarshal. %v", err)
		}
		lastNode.Next = newNodeID
		if nodeBytes, err = proto.Marshal(lastNode); err != nil {
			return fmt.Errorf("Could not marshal. %v", err)
		}
		if err = bucket.Put(backKey, nodeBytes); err != nil {
			return fmt.Errorf("Could not save changes to the last node. %v", err)
		}
		newNode.Prev = backKey
		if nodeBytes, err = proto.Marshal(newNode); err != nil {
			return fmt.Errorf("Could not marshal. %v", err)
		}
		if err = bucket.Put(newNodeID, nodeBytes); err != nil {
			return fmt.Errorf("Could not save the new node. %v", err)
		}
		return bucket.Put([]byte("BACK"), newNodeID)
	})
}
func (ll *LinkedList) PushFront(data []byte) error {
	if data == nil {
		return fmt.Errorf("Empty data")
	}
	return (*bbolt.DB)(ll.db).Update(func(tx *bbolt.Tx) error {
		bucket := tx.Bucket(ll.name)
		if bucket == nil {
			return ErrBucketNotFound
		}
		var (
			id        uint64
			err       error
			nodeBytes []byte
		)
		id, _ = bucket.NextSequence()
		newNodeID := byteID(id)
		newNode := &pb.LinkedListNode{
			Data: data,
			Next: nil,
			Prev: nil,
		}
		frontKey := bucket.Get([]byte("FRONT"))
		if frontKey == nil {
			if nodeBytes, err = proto.Marshal(newNode); err != nil {
				return fmt.Errorf("Could not marshal. %v", err)
			}
			if err = bucket.Put(newNodeID, nodeBytes); err != nil {
				return fmt.Errorf("Could not save the first node. %v", err)
			}
			if err = bucket.Put([]byte("FRONT"), newNodeID); err != nil {
				return fmt.Errorf("Could not set front of the linked list. %v", err)
			}
			if err = bucket.Put([]byte("BACK"), newNodeID); err != nil {
				return fmt.Errorf("Could not set back of the linked list. %v", err)
			}
		}
		nodeBytes = bucket.Get(frontKey)
		if nodeBytes == nil {
			return ErrDoesNotExist
		}
		firstNode := &pb.LinkedListNode{}
		if err = proto.Unmarshal(nodeBytes, firstNode); err != nil {
			return fmt.Errorf("Could not unmarshal. %v", err)
		}
		firstNode.Prev = newNodeID
		if nodeBytes, err = proto.Marshal(firstNode); err != nil {
			return fmt.Errorf("Could not marshal. %v", err)
		}
		if err = bucket.Put(frontKey, nodeBytes); err != nil {
			return fmt.Errorf("Could not save changes to the first node. %v", err)
		}
		newNode.Next = frontKey
		if nodeBytes, err = proto.Marshal(newNode); err != nil {
			return fmt.Errorf("Could not marshal. %v", err)
		}
		if err = bucket.Put(newNodeID, nodeBytes); err != nil {
			return fmt.Errorf("Could not save the new node. %v", err)
		}
		return bucket.Put([]byte("FRONT"), newNodeID)
	})
}
func (ll *LinkedList) Front() (i *Item, err error) {
	return i, (*bbolt.DB)(ll.db).View(func(tx *bbolt.Tx) error {
		k, val, empty, err := ll.first()
		if err != nil {
			return err
		}
		if empty {
			i, err = nil, nil
			return err
		}
		llFirstNode := &pb.LinkedListNode{}
		if err := proto.Unmarshal(val, llFirstNode); err != nil {
			return fmt.Errorf("Could not unmarshal. %v", err)
		}
		i = &Item{
			Data: &storedData{
				key:                k,
				value:              llFirstNode.Data,
				internalLinkedList: ll,
			},
		}
		return nil
	})
}
func (ll *LinkedList) Back() (i *Item, err error) {
	return i, (*bbolt.DB)(ll.db).View(func(tx *bbolt.Tx) error {
		k, val, empty, err := ll.last()
		if err != nil {
			return err
		}
		if empty {
			i, err = nil, nil
			return err
		}
		llLastNode := &pb.LinkedListNode{}
		if err := proto.Unmarshal(val, llLastNode); err != nil {
			return fmt.Errorf("Could not unmarshal. %v", err)
		}
		i = &Item{
			Data: &storedData{
				key:                k,
				value:              llLastNode.Data,
				internalLinkedList: ll,
			},
		}
		return nil
	})
}
func (ll *LinkedList) first() (key, val []byte, empty bool, err error) {
	err = (*bbolt.DB)(ll.db).View(func(tx *bbolt.Tx) error {
		var bucket *bbolt.Bucket
		if bucket = tx.Bucket(ll.name); bucket == nil {
			return ErrBucketNotFound
		}
		key = bucket.Get([]byte("FRONT"))
		if key == nil {
			empty = true
		} else {
			empty = false
			val = bucket.Get(key)
		}
		return nil
	})
	return
}
func (ll *LinkedList) last() (key, val []byte, empty bool, err error) {
	err = (*bbolt.DB)(ll.db).View(func(tx *bbolt.Tx) error {
		var bucket *bbolt.Bucket
		if bucket = tx.Bucket(ll.name); bucket == nil {
			return ErrBucketNotFound
		}
		key = bucket.Get([]byte("BACK"))
		if key == nil {
			empty = true
		} else {
			empty = false
			val = bucket.Get(key)
		}
		return nil
	})
	return
}
func (ll *LinkedList) Get(val []byte) (*Item, error) {
	front, err := ll.Front()
	if err != nil {
		return nil, err
	}
	if front == nil {
		return nil, fmt.Errorf("Empty list")
	}
	if val == nil {
		return nil, fmt.Errorf("Empty val")
	}
	var it *Item
	for k := front; k != nil; k = k.Next() {
		if bytes.Equal(val, k.Data.Value()) {
			it = k
			break
		}
	}
	return it, nil
}
func (ll *LinkedList) GetFunc(val interface{}, equal func(a interface{}, b []byte) bool) (*Item, error) {
	front, err := ll.Front()
	if err != nil {
		return nil, err
	}
	if front == nil {
		return nil, fmt.Errorf("Empty list")
	}
	if val == nil {
		return nil, fmt.Errorf("Empty val")
	}
	if equal == nil {
		return nil, fmt.Errorf("Empty comparing function")
	}
	var it *Item
	for k := front; k != nil; k = k.Next() {
		if equal(val, k.Data.Value()) {
			it = k
			break
		}
	}
	return it, nil
}
func (ll *LinkedList) GetNext(val []byte, mark *Item) (*Item, error) {
	_, _, empty, err := ll.first()
	if err != nil {
		return nil, err
	}
	if empty {
		return nil, fmt.Errorf("Empty list")
	}
	if val == nil {
		return nil, fmt.Errorf("Empty val")
	}
	if mark == nil {
		return nil, fmt.Errorf("Empty mark")
	}
	var it *Item
	for k := mark; k != nil; k = k.Next() {
		if bytes.Equal(val, k.Data.Value()) {
			it = k
			break
		}
	}
	return it, nil
}