com.google.code.fqueue.memcached.storage.FSStorage.java Source code

Java tutorial

Introduction

Here is the source code for com.google.code.fqueue.memcached.storage.FSStorage.java

Source

/*
 *  Copyright 2011 sunli [sunli1223@gmail.com][weibo.com@sunli1223]
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.google.code.fqueue.memcached.storage;

import java.io.IOException;
import java.util.AbstractQueue;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.google.code.fqueue.FQueue;
import com.google.code.fqueue.exception.ConfigException;
import com.google.code.fqueue.util.Config;
import com.google.code.fqueue.util.JVMMonitor;
import com.thimbleware.jmemcached.LocalCacheElement;
import com.thimbleware.jmemcached.protocol.exceptions.ClientException;
import com.thimbleware.jmemcached.protocol.exceptions.DatabaseException;
import com.thimbleware.jmemcached.storage.CacheStorage;

/**
 * MemcachedFQueue Memcached??key???
 * 
 * @author sunli
 * @date 2011-5-11
 * @version $Id$
 */
public class FSStorage implements CacheStorage<String, LocalCacheElement> {
    /**
     * ?
     */
    private Map<String, AbstractQueue<byte[]>> queuemMap = new ConcurrentHashMap<String, AbstractQueue<byte[]>>();
    private final ReentrantLock lock = new ReentrantLock();
    private final static Log log = LogFactory.getLog(FSStorage.class);
    /**
     * ????? ???M
     */
    private final static int logSize = 1024 * 1024 * Integer.parseInt(Config.getSetting("logsize"));
    /**
     * ?
     */
    private final static String dbpath = Config.getSetting("path").trim();
    /**
     * ?map
     */
    private static Map<String, String> authorizationMap = new ConcurrentHashMap<String, String>(20);
    static {
        loadAuthorization();
    }

    private static void loadAuthorization() {
        String line = Config.getSetting("authorization");
        if (line != null) {
            if (line.indexOf("_") != -1) {
                log.error("?????'_'?");
            }
            String[] group = line.split("@@");
            for (int i = 0, groupLen = group.length; i < groupLen; i++) {
                String[] item = group[i].split("\\|");
                if (item.length == 2) {
                    authorizationMap.put(item[0], item[1]);
                }
            }
        }
    }

    /**
     * ???????
     */
    private static void reloadAuthorization() {
        Config.reload();
        loadAuthorization();
    }

    @Override
    public int capacity() {
        return 0;
    }

    @Override
    public void clear() throws DatabaseException, Exception {
    }

    @Override
    public void close() throws IOException {
        for (String key : queuemMap.keySet()) {
            ((FQueue) queuemMap.get(key)).close();
        }
        log.info("close queue");
    }

    /**
     * get???
     * 
     * @param keystring
     * @return
     * @throws ClientException
     */
    private LocalCacheElement getProtocol(String keystring) throws ClientException {
        // ?
        if (keystring.startsWith("size")) {
            try {
                // size|bbs
                // size?????????
                String[] clientInfo = QueueClient.parse(keystring, '|');
                if (clientInfo.length < 2 || authorizationMap.containsKey(clientInfo[1]) == false) {
                    return null;
                }
                AbstractQueue<byte[]> sizeQueue = getClientQueue(clientInfo[1]);
                if (sizeQueue == null) {
                    return null;
                }
                int size = sizeQueue.size();
                LocalCacheElement element = new LocalCacheElement(keystring, 0, 0, 0);
                element.setData(String.valueOf(size).getBytes());
                return element;
            } catch (Exception e) {
                log.error("getsize " + keystring + "error", e);
                return null;
            }
        }
        // 
        if (keystring.startsWith("clear")) {
            try {
                // clear|bbs|pass
                String[] clientInfo = QueueClient.parse(keystring, '|');
                if (clientInfo.length < 3 || valid(clientInfo[1], clientInfo[2]) == false) {
                    throw new ClientException("Authorization error");
                }
                AbstractQueue<byte[]> queue = getClientQueue(clientInfo[1]);
                queue.clear();
                LocalCacheElement element = new LocalCacheElement(keystring, 0, 0, 0);
                element.setData(String.valueOf(queue.size()).getBytes());
                return element;
            } catch (Exception e) {
                log.error("getsize " + keystring + "error", e);
                return null;
            }
        }
        // ????
        if (keystring.startsWith("reload")) {
            try {
                // reload|bbs|pass
                String[] clientInfo = QueueClient.parse(keystring, '|');
                if (clientInfo.length < 3 || valid(clientInfo[1], clientInfo[2]) == false) {
                    throw new ClientException("Authorization error");
                }
                reloadAuthorization();
                LocalCacheElement element = new LocalCacheElement(keystring, 0, 0, 0);
                element.setData("reloadAuthorization".getBytes());
                return element;
            } catch (ConfigException e) {
                log.error(e.getMessage(), e);
            } catch (Exception e) {
                log.error("reloadAuthorization error", e);
                return null;
            }
        }
        // ????
        if (keystring.startsWith("monitor")) {
            try {
                // size|bbs
                // size?????????
                String[] clientInfo = QueueClient.parse(keystring, '|');
                if (clientInfo.length < 2) {
                    return null;
                }
                String items = clientInfo[1];
                StringBuilder stats = new StringBuilder();
                if (items != null) {
                    String[] itemList = StringUtils.split(items, ",");
                    for (int i = 0, len = itemList.length; i < len; i++) {
                        if (i > 0) {
                            stats.append("\r\n");
                        }
                        String data = JVMMonitor.getMonitorStats(itemList[i]);
                        stats.append(data);
                    }
                } else {
                    stats.append("need items");
                }

                LocalCacheElement element = new LocalCacheElement(keystring, 0, 0, 0);
                element.setData(stats.toString().getBytes());
                return element;
            } catch (Exception e) {
                log.error("monitor " + keystring + "error", e);
                return null;
            }
        }
        throw new ClientException(keystring + " command Unsupported now");
    }

    @Override
    public LocalCacheElement get(String keystring) {
        try {
            if (keystring.indexOf("_") == -1) {
                return getProtocol(keystring);
            }
            String[] clientInfo = QueueClient.parseWithCache(keystring);
            if (valid(clientInfo[0], clientInfo[1])) {
                byte[] data;
                data = getClientQueue(clientInfo[0]).poll();
                if (data != null) {
                    LocalCacheElement element = new LocalCacheElement(keystring, 0, 0, 0);
                    element.setData(data);
                    return element;
                } else {
                    log.info("queue empty");
                }
            } else {
                log.error("unvalid " + keystring);
                throw new ClientException("Authorization error");
            }
        } catch (Exception e) {
            log.error("get queue " + keystring + " error", e);
            return null;
        }
        return null;
    }

    @Override
    public long getMemoryCapacity() {
        return 0;
    }

    @Override
    public long getMemoryUsed() {
        return 0;
    }

    @Override
    public Set<String> keySet() {
        return null;
    }

    @Override
    public LocalCacheElement put(String keystring, LocalCacheElement e) throws DatabaseException, Exception {
        String[] clientInfo = QueueClient.parseWithCache(keystring);
        if (valid(clientInfo[0], clientInfo[1])) {// ??
            getClientQueue(clientInfo[0]).add(e.getData());
            return null;
        } else {
            throw new ClientException("Authorization error");
        }
    }

    @Override
    public LocalCacheElement putIfAbsent(String keystring, LocalCacheElement e)
            throws DatabaseException, Exception {
        String[] clientInfo = QueueClient.parseWithCache(keystring);
        if (valid(clientInfo[0], clientInfo[1])) {// ??
            getClientQueue(clientInfo[0]).add(e.getData());
            return null;
        } else {
            throw new ClientException("Authorization error");
        }

    }

    @Override
    public LocalCacheElement remove(String key) throws DatabaseException, Exception {
        return null;
    }

    @Override
    public boolean replace(String keystring, LocalCacheElement old, LocalCacheElement prepend)
            throws DatabaseException, Exception {
        return false;
    }

    @Override
    public LocalCacheElement replace(String key, LocalCacheElement placeHolder)
            throws DatabaseException, Exception {
        return null;
    }

    @Override
    public long size() {
        return 0;
    }

    private boolean valid(String appid, String pwd) {
        return pwd.equals(authorizationMap.get(appid));
    }

    /**
     * ??? ??create??
     * 
     * @param name
     * @return
     * @throws Exception
     */
    private AbstractQueue<byte[]> getClientQueue(String name, boolean create) throws Exception {
        AbstractQueue<byte[]> queue = queuemMap.get(name);
        if (queue == null) {
            if (create == true) {
                lock.lock();
                try {
                    queue = queuemMap.get(name);
                    if (queue == null) {
                        queue = new FQueue(dbpath + "/" + name, logSize);
                        queuemMap.put(name, queue);
                    }
                } finally {
                    lock.unlock();
                }
            }
        }
        return queue;
    }

    /**
     * ???
     * 
     * @param name
     * @return
     * @throws Exception
     */
    private AbstractQueue<byte[]> getClientQueue(String name) throws Exception {
        return getClientQueue(name, true);
    }
}