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

COVERAGE SUMMARY FOR SOURCE FILE [BaseGetOpImpl.java]

nameclass, %method, %block, %line, %
BaseGetOpImpl.java100% (1/1)100% (7/7)82%  (370/451)95%  (79.4/84)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class BaseGetOpImpl100% (1/1)100% (7/7)82%  (370/451)95%  (79.4/84)
handleRead (ByteBuffer): void 100% (1/1)74%  (174/235)91%  (31.7/35)
handleLine (String): void 100% (1/1)83%  (85/103)94%  (18.8/20)
<static initializer> 100% (1/1)86%  (12/14)92%  (1.8/2)
BaseGetOpImpl (String, OperationCallback, Collection): void 100% (1/1)100% (28/28)100% (10/10)
getKeys (): Collection 100% (1/1)100% (3/3)100% (1/1)
initialize (): void 100% (1/1)100% (63/63)100% (14/14)
wasCancelled (): void 100% (1/1)100% (5/5)100% (2/2)

1package net.spy.memcached.protocol.ascii;
2 
3import java.nio.ByteBuffer;
4import java.util.Collection;
5 
6import net.spy.memcached.KeyUtil;
7import net.spy.memcached.ops.GetOperation;
8import net.spy.memcached.ops.GetsOperation;
9import net.spy.memcached.ops.OperationCallback;
10import net.spy.memcached.ops.OperationState;
11import net.spy.memcached.ops.OperationStatus;
12 
13/**
14 * Base class for get and gets handlers.
15 */
16abstract class BaseGetOpImpl extends OperationImpl {
17 
18        private static final OperationStatus END = new OperationStatus(true, "END");
19        private final String cmd;
20        private final Collection<String> keys;
21        private String currentKey = null;
22        private long casValue=0;
23        private int currentFlags = 0;
24        private byte[] data = null;
25        private int readOffset = 0;
26        private byte lookingFor = '\0';
27 
28        public BaseGetOpImpl(String c,
29                        OperationCallback cb, Collection<String> k) {
30                super(cb);
31                cmd=c;
32                keys=k;
33        }
34 
35        /**
36         * Get the keys this GetOperation is looking for.
37         */
38        public final Collection<String> getKeys() {
39                return keys;
40        }
41 
42        @Override
43        public final void handleLine(String line) {
44                if(line.equals("END")) {
45                        getLogger().debug("Get complete!");
46                        getCallback().receivedStatus(END);
47                        transitionState(OperationState.COMPLETE);
48                        data=null;
49                } else if(line.startsWith("VALUE ")) {
50                        getLogger().debug("Got line %s", line);
51                        String[] stuff=line.split(" ");
52                        assert stuff[0].equals("VALUE");
53                        currentKey=stuff[1];
54                        currentFlags=Integer.parseInt(stuff[2]);
55                        data=new byte[Integer.parseInt(stuff[3])];
56                        if(stuff.length > 4) {
57                                casValue=Long.parseLong(stuff[4]);
58                        }
59                        readOffset=0;
60                        getLogger().debug("Set read type to data");
61                        setReadType(OperationReadType.DATA);
62                } else {
63                        assert false : "Unknown line type: " + line;
64                }
65        }
66 
67        @Override
68        public final void handleRead(ByteBuffer b) {
69                assert currentKey != null;
70                assert data != null;
71                // This will be the case, because we'll clear them when it's not.
72                assert readOffset <= data.length
73                        : "readOffset is " + readOffset + " data.length is " + data.length;
74 
75                getLogger().debug("readOffset: %d, length: %d",
76                                readOffset, data.length);
77                // If we're not looking for termination, we're still looking for data
78                if(lookingFor == '\0') {
79                        int toRead=data.length - readOffset;
80                        int available=b.remaining();
81                        toRead=Math.min(toRead, available);
82                        getLogger().debug("Reading %d bytes", toRead);
83                        b.get(data, readOffset, toRead);
84                        readOffset+=toRead;
85                }
86                // Transition us into a ``looking for \r\n'' kind of state if we've
87                // read enough and are still in a data state.
88                if(readOffset == data.length && lookingFor == '\0') {
89                        // The callback is most likely a get callback.  If it's not, then
90                        // it's a gets callback.
91                        try {
92                                GetOperation.Callback gcb=(GetOperation.Callback)getCallback();
93                                gcb.gotData(currentKey, currentFlags, data);
94                        } catch(ClassCastException e) {
95                                GetsOperation.Callback gcb=(GetsOperation.Callback)
96                                        getCallback();
97                                gcb.gotData(currentKey, currentFlags, casValue, data);
98                        }
99                        lookingFor='\r';
100                }
101                // If we're looking for an ending byte, let's go find it.
102                if(lookingFor != '\0' && b.hasRemaining()) {
103                        do {
104                                byte tmp=b.get();
105                                assert tmp == lookingFor : "Expecting " + lookingFor + ", got "
106                                        + (char)tmp;
107                                switch(lookingFor) {
108                                        case '\r': lookingFor='\n'; break;
109                                        case '\n': lookingFor='\0'; break;
110                                        default:
111                                                assert false: "Looking for unexpected char: "
112                                                        + (char)lookingFor;
113                                }
114                        } while(lookingFor != '\0' && b.hasRemaining());
115                        // Completed the read, reset stuff.
116                        if(lookingFor == '\0') {
117                                currentKey=null;
118                                data=null;
119                                readOffset=0;
120                                currentFlags=0;
121                                getLogger().debug("Setting read type back to line.");
122                                setReadType(OperationReadType.LINE);
123                        }
124                }
125        }
126 
127        @Override
128        public final void initialize() {
129                // Figure out the length of the request
130                int size=6; // Enough for gets\r\n
131                Collection<byte[]> keyBytes=KeyUtil.getKeyBytes(keys);
132                for(byte[] k : keyBytes) {
133                        size+=k.length;
134                        size++;
135                }
136                ByteBuffer b=ByteBuffer.allocate(size);
137                b.put(cmd.getBytes());
138                for(byte[] k : keyBytes) {
139                        b.put((byte)' ');
140                        b.put(k);
141                }
142                b.put("\r\n".getBytes());
143                b.flip();
144                setBuffer(b);
145        }
146 
147        @Override
148        protected final void wasCancelled() {
149                getCallback().receivedStatus(CANCELLED);
150        }
151 
152}

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