EMMA Coverage Report (generated Tue Oct 27 11:32:50 PDT 2009)
[all classes][net.spy.memcached.protocol.binary]

COVERAGE SUMMARY FOR SOURCE FILE [MultiGetOperationImpl.java]

nameclass, %method, %block, %line, %
MultiGetOperationImpl.java100% (1/1)100% (6/6)90%  (283/313)98%  (56.9/58)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class MultiGetOperationImpl100% (1/1)100% (6/6)90%  (283/313)98%  (56.9/58)
finishedPayload (byte []): void 100% (1/1)65%  (53/82)92%  (11/12)
opaqueIsValid (): boolean 100% (1/1)94%  (15/16)93%  (0.9/1)
MultiGetOperationImpl (Collection, OperationCallback): void 100% (1/1)100% (42/42)100% (8/8)
addKey (String): int 100% (1/1)100% (33/33)100% (7/7)
getKeys (): Collection 100% (1/1)100% (4/4)100% (1/1)
initialize (): void 100% (1/1)100% (136/136)100% (29/29)

1package net.spy.memcached.protocol.binary;
2 
3import static net.spy.memcached.protocol.binary.GetOperationImpl.EXTRA_HDR_LEN;
4 
5import java.io.IOException;
6import java.nio.ByteBuffer;
7import java.util.Collection;
8import java.util.HashMap;
9import java.util.HashSet;
10import java.util.Map;
11 
12import net.spy.memcached.KeyUtil;
13import net.spy.memcached.ops.GetOperation;
14import net.spy.memcached.ops.OperationCallback;
15import net.spy.memcached.ops.OperationState;
16 
17class MultiGetOperationImpl extends OperationImpl implements GetOperation {
18 
19        private static final int CMD_GETQ=9;
20 
21        private final Map<Integer, String> keys=new HashMap<Integer, String>();
22        private final Map<Integer, byte[]> bkeys=new HashMap<Integer, byte[]>();
23        private final Map<String, Integer> rkeys=new HashMap<String, Integer>();
24 
25        private final int terminalOpaque=generateOpaque();
26 
27        public MultiGetOperationImpl(Collection<String> k, OperationCallback cb) {
28                super(-1, -1, cb);
29                for(String s : new HashSet<String>(k)) {
30                        addKey(s);
31                }
32        }
33 
34        /**
35         * Add a key (and return its new opaque value).
36         */
37        protected int addKey(String k) {
38                Integer rv=rkeys.get(k);
39                if(rv == null) {
40                        rv=generateOpaque();
41                        keys.put(rv, k);
42                        bkeys.put(rv, KeyUtil.getKeyBytes(k));
43                        rkeys.put(k, rv);
44                }
45                return rv;
46        }
47 
48        @Override
49        public void initialize() {
50                int size=(1+keys.size()) * MIN_RECV_PACKET;
51                for(byte[] b : bkeys.values()) {
52                        size += b.length;
53                }
54                // set up the initial header stuff
55                ByteBuffer bb=ByteBuffer.allocate(size);
56                for(Map.Entry<Integer, byte[]> me : bkeys.entrySet()) {
57                        final byte[] keyBytes=me.getValue();
58 
59                        // Custom header
60                        bb.put(REQ_MAGIC);
61                        bb.put((byte)CMD_GETQ);
62                        bb.putShort((short)keyBytes.length);
63                        bb.put((byte)0); // extralen
64                        bb.put((byte)0); // data type
65                        bb.putShort((short)0); // reserved
66                        bb.putInt(keyBytes.length);
67                        bb.putInt(me.getKey());
68                        bb.putLong(0); // cas
69                        // the actual key
70                        bb.put(keyBytes);
71                }
72                // Add the noop
73                bb.put(REQ_MAGIC);
74                bb.put((byte)NoopOperationImpl.CMD);
75                bb.putShort((short)0);
76                bb.put((byte)0); // extralen
77                bb.put((byte)0); // data type
78                bb.putShort((short)0); // reserved
79                bb.putInt(0);
80                bb.putInt(terminalOpaque);
81                bb.putLong(0); // cas
82 
83                bb.flip();
84                setBuffer(bb);
85        }
86 
87        @Override
88        protected void finishedPayload(byte[] pl) throws IOException {
89                if(responseOpaque == terminalOpaque) {
90                        getCallback().receivedStatus(STATUS_OK);
91                        transitionState(OperationState.COMPLETE);
92                } else if(errorCode != 0) {
93                        getLogger().warn("Error on key %s:  %s (%d)",
94                                keys.get(responseOpaque), new String(pl), errorCode);
95                } else {
96                        final int flags=decodeInt(pl, 0);
97                        final byte[] data=new byte[pl.length - EXTRA_HDR_LEN];
98                        System.arraycopy(pl, EXTRA_HDR_LEN, data,
99                                        0, pl.length-EXTRA_HDR_LEN);
100                        Callback cb=(Callback)getCallback();
101                        cb.gotData(keys.get(responseOpaque), flags, data);
102                }
103                resetInput();
104        }
105 
106        @Override
107        protected boolean opaqueIsValid() {
108                return responseOpaque == terminalOpaque
109                        || keys.containsKey(responseOpaque);
110        }
111 
112        public Collection<String> getKeys() {
113                return keys.values();
114        }
115 
116}

[all classes][net.spy.memcached.protocol.binary]
EMMA 2.0.5312 (C) Vladimir Roubtsov