func set(c appengine.Context, item []*Item, value [][]byte, policy pb.MemcacheSetRequest_SetPolicy) []error {
	req := &pb.MemcacheSetRequest{
		Item: make([]*pb.MemcacheSetRequest_Item, len(item)),
	}
	for i, t := range item {
		p := &pb.MemcacheSetRequest_Item{
			Key: []byte(t.Key),
		}
		if value == nil {
			p.Value = t.Value
		} else {
			p.Value = value[i]
		}
		if t.Flags != 0 {
			p.Flags = proto.Uint32(t.Flags)
		}
		if t.Expiration != 0 {
			p.ExpirationTime = proto.Uint32(uint32(t.Expiration))
		}
		if t.casID != 0 {
			p.CasId = proto.Uint64(t.casID)
			p.ForCas = proto.Bool(true)
		}
		p.SetPolicy = pb.NewMemcacheSetRequest_SetPolicy(policy)
		req.Item[i] = p
	}
	res := &pb.MemcacheSetResponse{}
	e := make([]error, len(item))
	err := c.Call("memcache", "Set", req, res, nil)
	if err == nil && len(e) != len(res.SetStatus) {
		err = ErrServerError
	}
	if err != nil {
		for i := range e {
			e[i] = err
		}
		return e
	}
	for i := range e {
		switch res.SetStatus[i] {
		case pb.MemcacheSetResponse_STORED:
			e[i] = nil
		case pb.MemcacheSetResponse_NOT_STORED:
			e[i] = ErrNotStored
		case pb.MemcacheSetResponse_EXISTS:
			e[i] = ErrCASConflict
		default:
			e[i] = ErrServerError
		}
	}
	return e
}
set sets the given items using the given conflict resolution policy.
The returned slice will have the same length as the input slice.
If value is not nil, each element should correspond to an item.
package memcache
import (
	"bytes"
	"errors"
	"gob"
	"json"
	"appengine"
	"appengine_internal"
	"goprotobuf.googlecode.com/hg/proto"
	pb "appengine_internal/memcache"
)
var (
	ErrCacheMiss = errors.New("memcache: cache miss")
	ErrCASConflict = errors.New("memcache: compare-and-swap conflict")
	ErrNoStats = errors.New("memcache: no statistics available")
	ErrNotStored = errors.New("memcache: item not stored")
	ErrServerError = errors.New("memcache: server error")
)
type Item struct {
	Key string
	Value []byte
	Object interface{}
	Flags uint32
	Expiration int32
	casID uint64
}
func protoToItem(p *pb.MemcacheGetResponse_Item) *Item {
	return &Item{
		Key:        string(p.Key),
		Value:      p.Value,
		Flags:      proto.GetUint32(p.Flags),
		Expiration: proto.GetInt32(p.ExpiresInSeconds),
		casID:      proto.GetUint64(p.CasId),
	}
}
func Get(c appengine.Context, key string) (*Item, error) {
	m, err := GetMulti(c, []string{key})
	if err != nil {
		return nil, err
	}
	if _, ok := m[key]; !ok {
		return nil, ErrCacheMiss
	}
	return m[key], nil
}
func GetMulti(c appengine.Context, key []string) (map[string]*Item, error) {
	keyAsBytes := make([][]byte, len(key))
	for i, k := range key {
		keyAsBytes[i] = []byte(k)
	}
	req := &pb.MemcacheGetRequest{
		Key:    keyAsBytes,
		ForCas: proto.Bool(true),
	}
	res := &pb.MemcacheGetResponse{}
	if err := c.Call("memcache", "Get", req, res, nil); err != nil {
		return nil, err
	}
	m := make(map[string]*Item, len(res.Item))
	for _, p := range res.Item {
		t := protoToItem(p)
		m[t.Key] = t
	}
	return m, nil
}
func Delete(c appengine.Context, key string) error {
	e := DeleteMulti(c, []string{key})
	return e[0]
}
func DeleteMulti(c appengine.Context, key []string) []error {
	req := &pb.MemcacheDeleteRequest{
		Item: make([]*pb.MemcacheDeleteRequest_Item, len(key)),
	}
	for i, k := range key {
		req.Item[i] = &pb.MemcacheDeleteRequest_Item{Key: []byte(k)}
	}
	res := &pb.MemcacheDeleteResponse{}
	e := make([]error, len(key))
	err := c.Call("memcache", "Delete", req, res, nil)
	if err == nil && len(e) != len(res.DeleteStatus) {
		err = ErrServerError
	}
	if err != nil {
		for i := range e {
			e[i] = err
		}
		return e
	}
	for i, s := range res.DeleteStatus {
		switch s {
		case pb.MemcacheDeleteResponse_DELETED:
			e[i] = nil
		case pb.MemcacheDeleteResponse_NOT_FOUND:
			e[i] = ErrCacheMiss
		default:
			e[i] = ErrServerError
		}
	}
	return e
}