// Path: src/main/java/com/hyd/ssdb/protocol/Request.java
// public class Request {
// 
//     private Charset charset = AbstractClient.DEFAULT_CHARSET;
// 
//     private Block header;
// 
//     private Server forceServer;     // 强制指定请求的发送地址
// 
//     private final List<Block> blocks = new ArrayList<Block>();
// 
//     public Request(String command) {
//         String[] tokens = command.split("\\s+");
//         readTokens(tokens);
//     }
// 
//     public Request(Object... tokens) {
//         if (tokens.length == 0) {
//             throw new SsdbException("command is empty");
//         }
// 
//         readTokens(tokens);
//     }
// 
//     public Server getForceServer() {
//         return forceServer;
//     }
// 
//     public void setForceServer(Server forceServer) {
//         this.forceServer = forceServer;
//     }
// 
//     public Charset getCharset() {
//         return charset;
//     }
// 
//     public void setCharset(Charset charset) {
//         this.charset = charset;
//     }
// 
//     private void readTokens(Object[] tokens) {
// 
//         // 一个命令至少有 command 和 key 两个部分，然后可能有后面其他参数
//         if (isKeyRequired(tokens) && tokens.length < 2) {
//             throw new SsdbException("Command '" + tokens[0] + "' has no parameters or not supported.");
//         }
// 
//         this.header = new Block(tokens[0].toString().getBytes(charset));
// 
//         for (int i = 1; i < tokens.length; i++) {
//             Object token = tokens[i];
//             Block block;
//             if (token instanceof byte[]) {
//                 block = new Block((byte[]) token);
//             } else {
//                 block = new Block(token.toString().getBytes(charset));
//             }
//             this.blocks.add(block);
//         }
//     }
// 
//     private boolean isKeyRequired(Object[] tokens) {
//         if (tokens.length == 0) {
//             return true;
//         }
// 
//         return !(tokens[0].equals("dbsize") || tokens[0].equals("info"));
//     }
// 
//     public Block getHeader() {
//         return header;
//     }
// 
//     public List<Block> getBlocks() {
//         return blocks;
//     }
// 
//     public String getKey() {
//         return blocks.isEmpty() ? null : blocks.get(0).toString();    // 第一个参数一定是 key，用来决定其放在哪台服务器上
//     }
// 
//     @Override
//     public String toString() {
//         StringBuilder sb = new StringBuilder(header.toString()).append(' ');
// 
//         for (Block block : blocks) {
//             sb.append(block.toString()).append(' ');
//         }
// 
//         sb.deleteCharAt(sb.length() - 1);
//         return sb.toString();
//     }
// 
//     public byte[] toBytes() {
//         byte[][] byteArrays = new byte[blocks.size() + 2][];
// 
//         byteArrays[0] = header.toBytes();
//         for (int i = 0; i < blocks.size(); i++) {
//             byteArrays[i + 1] = blocks.get(i).toBytes();
//         }
//         byteArrays[byteArrays.length - 1] = new byte[]{'\n'};
// 
//         return Bytes.concat(byteArrays);
//     }
// }


import com.hyd.ssdb.protocol.Request;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.Random;
package com.hyd.ssdb;



/**
 * (description)
 * created at 15-12-3
 *
 * @author Yiding
 */
public class SsdbClientMultiThreadTest {

    private SsdbClient ssdbClient;

    @Before
    public void init() {
        this.ssdbClient = new SsdbClient("192.168.1.180", 8888);
    }

    @After
    public void finish() {
        this.ssdbClient.close();
    }


    @Test
    public void testMultiThread() throws Exception {
        for (int i = 0; i < 50; i++) {
            new Thread(new SsdbTask(ssdbClient)).start();
        }

        Thread.sleep(10000);
    }

    ////////////////////////////////////////////////////////////////

    private static class SsdbTask implements Runnable {

        private final SsdbClient ssdbClient;

        private Random random;

        public SsdbTask(SsdbClient ssdbClient) {
            this.ssdbClient = ssdbClient;
            random = new Random();
        }

        @Override
        public void run() {
            long start = System.currentTimeMillis();
            long end = start + 4000;

            while (System.currentTimeMillis() < end) {
// Path: src/main/java/com/hyd/ssdb/protocol/Request.java
// public class Request {
// 
//     private Charset charset = AbstractClient.DEFAULT_CHARSET;
// 
//     private Block header;
// 
//     private Server forceServer;     // 强制指定请求的发送地址
// 
//     private final List<Block> blocks = new ArrayList<Block>();
// 
//     public Request(String command) {
//         String[] tokens = command.split("\\s+");
//         readTokens(tokens);
//     }
// 
//     public Request(Object... tokens) {
//         if (tokens.length == 0) {
//             throw new SsdbException("command is empty");
//         }
// 
//         readTokens(tokens);
//     }
// 
//     public Server getForceServer() {
//         return forceServer;
//     }
// 
//     public void setForceServer(Server forceServer) {
//         this.forceServer = forceServer;
//     }
// 
//     public Charset getCharset() {
//         return charset;
//     }
// 
//     public void setCharset(Charset charset) {
//         this.charset = charset;
//     }
// 
//     private void readTokens(Object[] tokens) {
// 
//         // 一个命令至少有 command 和 key 两个部分，然后可能有后面其他参数
//         if (isKeyRequired(tokens) && tokens.length < 2) {
//             throw new SsdbException("Command '" + tokens[0] + "' has no parameters or not supported.");
//         }
// 
//         this.header = new Block(tokens[0].toString().getBytes(charset));
// 
//         for (int i = 1; i < tokens.length; i++) {
//             Object token = tokens[i];
//             Block block;
//             if (token instanceof byte[]) {
//                 block = new Block((byte[]) token);
//             } else {
//                 block = new Block(token.toString().getBytes(charset));
//             }
//             this.blocks.add(block);
//         }
//     }
// 
//     private boolean isKeyRequired(Object[] tokens) {
//         if (tokens.length == 0) {
//             return true;
//         }
// 
//         return !(tokens[0].equals("dbsize") || tokens[0].equals("info"));
//     }
// 
//     public Block getHeader() {
//         return header;
//     }
// 
//     public List<Block> getBlocks() {
//         return blocks;
//     }
// 
//     public String getKey() {
//         return blocks.isEmpty() ? null : blocks.get(0).toString();    // 第一个参数一定是 key，用来决定其放在哪台服务器上
//     }
// 
//     @Override
//     public String toString() {
//         StringBuilder sb = new StringBuilder(header.toString()).append(' ');
// 
//         for (Block block : blocks) {
//             sb.append(block.toString()).append(' ');
//         }
// 
//         sb.deleteCharAt(sb.length() - 1);
//         return sb.toString();
//     }
// 
//     public byte[] toBytes() {
//         byte[][] byteArrays = new byte[blocks.size() + 2][];
// 
//         byteArrays[0] = header.toBytes();
//         for (int i = 0; i < blocks.size(); i++) {
//             byteArrays[i + 1] = blocks.get(i).toBytes();
//         }
//         byteArrays[byteArrays.length - 1] = new byte[]{'\n'};
// 
//         return Bytes.concat(byteArrays);
//     }
// }


// Path: src/test/java/com/hyd/ssdb/SsdbClientMultiThreadTest.java
import com.hyd.ssdb.protocol.Request;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.Random;

package com.hyd.ssdb;



/**
 * (description)
 * created at 15-12-3
 *
 * @author Yiding
 */
public class SsdbClientMultiThreadTest {

    private SsdbClient ssdbClient;

    @Before
    public void init() {
        this.ssdbClient = new SsdbClient("192.168.1.180", 8888);
    }

    @After
    public void finish() {
        this.ssdbClient.close();
    }


    @Test
    public void testMultiThread() throws Exception {
        for (int i = 0; i < 50; i++) {
            new Thread(new SsdbTask(ssdbClient)).start();
        }

        Thread.sleep(10000);
    }

    ////////////////////////////////////////////////////////////////

    private static class SsdbTask implements Runnable {

        private final SsdbClient ssdbClient;

        private Random random;

        public SsdbTask(SsdbClient ssdbClient) {
            this.ssdbClient = ssdbClient;
            random = new Random();
        }

        @Override
        public void run() {
            long start = System.currentTimeMillis();
            long end = start + 4000;

            while (System.currentTimeMillis() < end) {
                ssdbClient.sendRequest(new Request(