func (ew *EventWarehouse) Pop(subID, pubID string, height agtypes.INT) ([]byte, error) {
	heights, err := ew.state.Get(subID, pubID)
	if err != nil {
		return nil, err
	}
	for i, h := range heights {
		if h == height {
			data := ew.database.Get(ew.GenerateID(subID, pubID, height))
			ew.state.Set(subID, pubID, append(heights[:i], heights[i+1:]...))
			ew.database.Delete(ew.GenerateID(subID, pubID, height))
			return data, nil
		}
	}
	return nil, fmt.Errorf("(sub: %s, pub: %s, height:%d) is invalid", subID, pubID, height)
}
Pop makes sure the one event can only be fetched once by deleting after fetched
package node
import (
	"bytes"
	"encoding/gob"
	"fmt"
	"github.com/pkg/errors"
	"github.com/tendermint/tmlibs/db"
	agtypes "github.com/Baptist-Publication/angine/types"
)
const (
	eventCenterStateKey = "eventwarehouse-state"
)
type EventWarehouse struct {
	database db.DB
	state    *EventWarehouseState
}
type EventWarehouseState struct {
	state map[string][]agtypes.INT
}
func NewEventWarehouse(database db.DB) *EventWarehouse {
	return &EventWarehouse{
		database: database,
		state:    newWarehouseState(),
	}
}
func newWarehouseState() *EventWarehouseState {
	return &EventWarehouseState{
		state: make(map[string][]agtypes.INT),
	}
}
func (ew *EventWarehouse) GenerateID(subID, pubID string, height agtypes.INT) []byte {
	return []byte(fmt.Sprintf("%s-%s-%d", subID, pubID, height))
}
func (ew *EventWarehouse) Batch() db.Batch {
	return ew.database.NewBatch()
}
func (ew *EventWarehouse) Push(batch db.Batch, subID, pubID string, height agtypes.INT, data []byte) {
	batch.Set(ew.GenerateID(subID, pubID, height), data)
	ew.state.Append(subID, pubID, height)
}
func (ew *EventWarehouse) Fetch(subID, pubID string, height agtypes.INT) ([]byte, error) {
	heights, err := ew.state.Get(subID, pubID)
	if err != nil {
		return nil, err
	}
	for i, h := range heights {
		if h == height {
			data := ew.database.Get(ew.GenerateID(subID, pubID, height))
			ew.state.Set(subID, pubID, append(heights[:i], heights[i+1:]...))
			return data, nil
		}
	}
	return nil, errors.Errorf("(sub: %s, pub: %s, height:%d) is invalid", subID, pubID, height)
}