func (m *metadata) getConsumer(name string) (int64, error) {
	if b, ok := m.co[name]; ok {
		return b, nil
	}
	oldsize := m.size
	newsize := m.size + 24 + int64(len(name))
	if err := m.extendFile(newsize); err != nil {
		return 0, err
	}
	m.size = newsize
	m.putConsumer(oldsize, name)
	return oldsize, nil
}
getConsumer either finds an existing consumer with the given name or initializes
a new consumer with the given name and stores it into the metadata file.
package bigqueue
import (
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"syscall"
	"github.com/grandecola/mmap"
)
const (
	cMetadataVersion  = 1
	cMetadataFileName = "metadata.dat"
	cMetadataSize = 56
)
var (
	ErrIncompatibleVersion = errors.New("incompatible format of the code and data")
)
type metadata struct {
	aa   *mmap.File
	co   map[string]int64
	file string
	size int64
}
func newMetadata(dataDir string, arenaSize int) (*metadata, error) {
	metaPath := filepath.Join(dataDir, cMetadataFileName)
	info, err := os.Stat(metaPath)
	switch {
	case err != nil && !os.IsNotExist(err):
		return nil, fmt.Errorf("error in reading metadata file :: %w", err)
	case err != nil && os.IsNotExist(err):
		return createFile(metaPath)
	default:
		return loadFile(metaPath, info.Size())
	}
}
func loadFile(metaPath string, size int64) (*metadata, error) {
	aa, err := newArena(metaPath, int(size))
	if err != nil {
		return nil, fmt.Errorf("error in creating arena for metadata file :: %w", err)
	}
	md := &metadata{
		aa:   aa,
		co:   make(map[string]int64),
		file: metaPath,
		size: size,
	}
	if md.getVersion() != cMetadataVersion {
		return nil, ErrIncompatibleVersion
	}
	base := int64(cMetadataSize)
	for i := 0; i < md.getNumConsumers(); i++ {
		name := md.getConsumerName(base)
		md.co[name] = base
		base += int64(len(name)) + 24
	}
	return md, nil
}
func createFile(metaPath string) (*metadata, error) {
	aa, err := newArena(metaPath, cMetadataSize)
	if err != nil {
		return nil, fmt.Errorf("error in creating arena for metadata file :: %w", err)
	}
	md := &metadata{
		aa:   aa,
		co:   make(map[string]int64),
		file: metaPath,
		size: cMetadataSize,
	}
	md.putVersion()
	return md, nil
}
func (m *metadata) getVersion() int {
	return int(m.aa.ReadUint64At(0))
}
func (m *metadata) putVersion() {
	m.aa.WriteUint64At(cMetadataVersion, 0)
}
func (m *metadata) getHead() (int, int) {
	return int(m.aa.ReadUint64At(8)), int(m.aa.ReadUint64At(16))
}
func (m *metadata) getTail() (int, int) {
	return int(m.aa.ReadUint64At(24)), int(m.aa.ReadUint64At(32))
}
func (m *metadata) putTail(aid, pos int) {
	m.aa.WriteUint64At(uint64(aid), 24)
	m.aa.WriteUint64At(uint64(pos), 32)
}
func (m *metadata) getArenaSize() int {
	return int(m.aa.ReadUint64At(40))
}
func (m *metadata) putArenaSize(size int) {
	m.aa.WriteUint64At(uint64(size), 40)
}
func (m *metadata) getNumConsumers() int {
	return int(m.aa.ReadUint64At(48))
}
func (m *metadata) putNumConsumers(size int) {
	m.aa.WriteUint64At(uint64(size), 48)
}
func (m *metadata) getConsumerLength(base int64) int {
	return int(m.aa.ReadUint64At(base))
}
func (m *metadata) putConsumerLength(base int64, length int) {
	m.aa.WriteUint64At(uint64(length), base)
}
func (m *metadata) getConsumerHead(base int64) (int, int) {
	return int(m.aa.ReadUint64At(base + 8)), int(m.aa.ReadUint64At(base + 16))
}
func (m *metadata) putConsumerHead(base int64, aid, pos int) {
	m.aa.WriteUint64At(uint64(aid), base+8)
	m.aa.WriteUint64At(uint64(pos), base+16)
}
func (m *metadata) getConsumerName(base int64) string {
	sb := &strings.Builder{}
	sb.Grow(m.getConsumerLength(base))
	_ = m.aa.ReadStringAt(sb, base+24)
	return sb.String()
}
func (m *metadata) putConsumerName(base int64, name string) {
	m.aa.WriteStringAt(name, base+24)
}
func (m *metadata) putConsumer(base int64, name string) {
	m.putConsumerLength(base, len(name))
	aid, offset := m.getHead()
	m.putConsumerHead(base, aid, offset)
	m.putConsumerName(base, name)
	m.putNumConsumers(m.getNumConsumers() + 1)
	m.co[name] = base
}