Package com.taobao.common.store.journal

Source Code of com.taobao.common.store.journal.JournalStore$InflyWriteData

/*
* (C) 2007-2012 Alibaba Group Holding Limited.
*
* 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.
* Authors:
*   dogun (yuexuqiang at gmail.com)
*/
package com.taobao.common.store.journal;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Logger;

import com.taobao.common.store.Store;
import com.taobao.common.store.journal.impl.ConcurrentIndexMap;
import com.taobao.common.store.journal.impl.LRUIndexMap;
import com.taobao.common.store.util.BytesKey;
import com.taobao.common.store.util.Util;


/**
* <b>һ��ͨ����־�ļ�ʵ�ֵ�key/value�ԵĴ洢</b>
*
* key������16�ֽ� <br />
* 1�������ļ�����־�ļ���һ�𣬲���¼�����ļ�<br />
* name.1 name.1.log<br />
* 2��dataΪ���������ݣ�˳���ţ�ʹ�����ü���<br />
* 3��logΪ����+key+ƫ����<br />
* 4���������ʱ�������name.1�����offset��length��Ȼ���¼��־���������ü�����Ȼ����������ڴ�����<br />
* 5��ɾ������ʱ����¼��־��ɾ���ڴ������������ļ��������жϴ�С�Ƿ������С�ˣ������������ˣ���ɾ�������ļ�����־�ļ�<br />
* 6����ȡ����ʱ��ֱ�Ӵ��ڴ������������ƫ����<br />
* 7����������ʱ���������<br />
* 8������ʱ������ÿһ��log�ļ���ͨ����־�IJ����ָ��ڴ�����<br />
*
* @author dogun (yuexuqiang at gmail.com)
*/
public class JournalStore implements Store, JournalStoreMBean {
    private final Log log = LogFactory.getLog(JournalStore.class);

    public static final int FILE_SIZE = 1024 * 1024 * 64; // 20M
    // public static final int ONE_DAY = 1000 * 60 * 60 * 24;
    public static final int HALF_DAY = 1000 * 60 * 60 * 12;
    protected static final int DEFAULT_MAX_BATCH_SIZE = 1024 * 1024 * 4;
    private final String path;
    private final String name;
    private final boolean force;

    protected IndexMap indices;
    private final Map<BytesKey, Long> lastModifiedMap = new ConcurrentHashMap<BytesKey, Long>();
    public Map<Integer, DataFile> dataFiles = new ConcurrentHashMap<Integer, DataFile>();
    protected Map<Integer, LogFile> logFiles = new ConcurrentHashMap<Integer, LogFile>();

    protected DataFile dataFile = null;
    protected LogFile logFile = null;
    private DataFileAppender dataFileAppender = null;
    private final AtomicInteger number = new AtomicInteger(0);
    private long intervalForCompact = HALF_DAY;
    private long intervalForRemove = HALF_DAY * 2 * 7;
    private volatile ScheduledExecutorService scheduledPool;

    private volatile long maxFileCount = Long.MAX_VALUE;

    protected int maxWriteBatchSize = DEFAULT_MAX_BATCH_SIZE;

    public static class InflyWriteData {
        public volatile byte[] data;
        public volatile int count;


        public InflyWriteData(final byte[] data) {
            super();
            this.data = data;
            this.count = 1;
        }

    }


    /**
     * Ĭ�Ϲ��캯��������path��ʹ��name��Ϊ�������������ļ�
     *
     * @param path
     * @param name
     * @param force
     * @throws IOException
     */
    public JournalStore(final String path, final String name, final boolean force, final boolean enabledIndexLRU)
            throws IOException {
        this(path, name, null, force, enabledIndexLRU, false);
    }


    /**
     * �Լ�ʵ�� ����ά�����
     *
     * @param path
     * @param name
     * @param indices
     * @param force
     * @param enabledIndexLRU
     * @throws IOException
     */
    public JournalStore(final String path, final String name, final IndexMap indices, final boolean force,
            final boolean enabledIndexLRU) throws IOException {
        this(path, name, indices, force, enabledIndexLRU, false);
    }


    /**
     *
     * @param path
     * @param name
     * @param force
     * @param enableIndexLRU
     * @param enabledDataFileCheck
     * @throws IOException
     */
    public JournalStore(final String path, final String name, final boolean force, final boolean enableIndexLRU,
            final boolean enabledDataFileCheck) throws IOException {
        this(path, name, null, force, enableIndexLRU, false);
    }


    /**
     * ���������ļ�����Ĺ��캯��
     *
     * @param path
     * @param name
     * @param force
     * @throws IOException
     */
    public JournalStore(final String path, final String name, final IndexMap indices, final boolean force,
            final boolean enableIndexLRU, final boolean enabledDataFileCheck) throws IOException {
        Util.registMBean(this, name);
        this.path = path;
        this.name = name;
        this.force = force;
        if (indices == null) {
            if (enableIndexLRU) {
                final long maxMemory = Runtime.getRuntime().maxMemory();
                // Ĭ��ʹ������ڴ��1/40���洢������Ŀǰֻ�ǹ���ֵ����Ҫ����
                final int capacity = (int) (maxMemory / 40 / 60);
                this.indices =
                        new LRUIndexMap(capacity, this.getPath() + File.separator + name + "_indexCache",
                            enableIndexLRU);
            }
            else {
                this.indices = new ConcurrentIndexMap();
            }
        }
        else {
            this.indices = indices;
        }
        this.dataFileAppender = new DataFileAppender(this);

        this.initLoad();
        // �����ǰû�п����ļ�������
        if (null == this.dataFile || null == this.logFile) {
            this.newDataFile();
        }

        // ����һ����ʱ�̣߳���Store4j�������ļ����ڽ�������.
        if (enabledDataFileCheck) {
            this.scheduledPool = Executors.newSingleThreadScheduledExecutor();
            this.scheduledPool.scheduleAtFixedRate(new DataFileCheckThread(), this.calcDelay(), HALF_DAY,
                TimeUnit.MILLISECONDS);
            log.warn("���������ļ���ʱ�����߳�");
        }

        // ��Ӧ�ñ��رյ�ʱ��,���û�йر��ļ�,�ر�֮.��ijЩ����ϵͳ����
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                try {
                    JournalStore.this.close();
                }
                catch (final IOException e) {
                    log.error("close error", e);
                }
            }
        });
    }


    /**
     * Ĭ�Ϲ��캯��������path��ʹ��name��Ϊ�������������ļ�
     *
     * @param path
     * @param name
     * @throws IOException
     */
    public JournalStore(final String path, final String name) throws IOException {
        this(path, name, false, false);
    }


    /*
     * (non-Javadoc)
     *
     * @see com.taobao.common.store.Store#add(byte[], byte[])
     */
    @Override
    public void add(final byte[] key, final byte[] data) throws IOException {
        this.add(key, data, false);
    }


    @Override
    public void add(final byte[] key, final byte[] data, final boolean force) throws IOException {
        // �ȼ���Ƿ��Ѿ����ڣ�����Ѿ������׳��쳣 �ж��ļ��Ƿ����ˣ����name.1�����offset����¼��־���������ü��������������ڴ�����
        this.checkParam(key, data);
        this.innerAdd(key, data, -1, force);

    }


    @Override
    public boolean remove(final byte[] key, final boolean force) throws IOException {
        return this.innerRemove(key, force);
    }


    /**
     * �������������ļ����ܹ��������ļ�����.
     *
     * @param key
     * @throws IOException
     */
    private void reuse(final byte[] key, final boolean sync) throws IOException {
        final byte[] value = this.get(key);
        final long oldLastTime = this.lastModifiedMap.get(new BytesKey(key));
        if (value != null && this.remove(key)) {
            this.innerAdd(key, value, oldLastTime, sync);
        }
    }


    /**
     * �����¸�ִ�����ڵ�delayʱ��.
     *
     * @return
     */
    private long calcDelay() {
        final Calendar date = new GregorianCalendar();
        date.setTime(new Date());
        final long currentTime = date.getTime().getTime();

        date.set(Calendar.HOUR_OF_DAY, 6);
        date.set(Calendar.MINUTE, 0);
        date.set(Calendar.SECOND, 0);

        long delay = date.getTime().getTime() - currentTime;
        // ��������6�㣬���������6��ʱ��
        if (delay < 0) {
            date.set(Calendar.HOUR_OF_DAY, 18);
            date.set(Calendar.MINUTE, 0);
            date.set(Calendar.SECOND, 0);
            delay = date.getTime().getTime() - currentTime;
            // ��������6��
            if (delay < 0) {
                delay += HALF_DAY;
            }
        }
        return delay;
    }


    /**
     * �ڲ��������
     *
     * @param key
     * @param data
     * @throws IOException
     */
    private OpItem innerAdd(final byte[] key, final byte[] data, final long oldLastTime, final boolean sync)
            throws IOException {
        final BytesKey k = new BytesKey(key);
        final OpItem op = new OpItem();
        op.op = OpItem.OP_ADD;
        this.dataFileAppender.store(op, k, data, sync);
        this.indices.put(k, op);
        if (oldLastTime == -1) {
            this.lastModifiedMap.put(k, System.currentTimeMillis());
        }
        else {
            this.lastModifiedMap.put(k, oldLastTime);
        }
        return op;
    }


    /*
     * (non-Javadoc)
     *
     * @see com.taobao.common.store.Store#get(byte[])
     */
    @Override
    public byte[] get(final byte[] key) throws IOException {
        byte[] data = null;
        final BytesKey bytesKey = new BytesKey(key);
        data = this.dataFileAppender.getDataFromInFlyWrites(bytesKey);
        if (data != null) {
            return data;
        }
        final OpItem op = this.indices.get(bytesKey);
        if (null != op) {

            final DataFile df = this.dataFiles.get(Integer.valueOf(op.number));
            if (null != df) {
                final ByteBuffer bf = ByteBuffer.wrap(new byte[op.length]);
                df.read(bf, op.offset);
                data = bf.array();
            }
            else {
                log.warn("�����ļ���ʧ��" + op);
                this.indices.remove(bytesKey);
                this.lastModifiedMap.remove(bytesKey);
            }
        }

        return data;
    }


    /*
     * (non-Javadoc)
     *
     * @see com.taobao.common.store.Store#iterator()
     */
    @Override
    public Iterator<byte[]> iterator() throws IOException {
        final Iterator<BytesKey> it = this.indices.keyIterator();
        return new Iterator<byte[]>() {
            @Override
            public boolean hasNext() {
                return it.hasNext();
            }


            @Override
            public byte[] next() {
                final BytesKey bk = it.next();
                if (null != bk) {
                    return bk.getData();
                }
                return null;
            }


            @Override
            public void remove() {
                throw new UnsupportedOperationException("��֧��ɾ������ֱ�ӵ���store.remove����");
            }
        };
    }


    /*
     * (non-Javadoc)
     *
     * @see com.taobao.common.store.Store#remove(byte[])
     */
    @Override
    public boolean remove(final byte[] key) throws IOException {
        return this.remove(key, false);
    }


    /**
     * ��ü�¼���Ǹ��ļ�����¼��־��ɾ���ڴ������������ļ��������жϴ�С�Ƿ������С�ˣ������������ˣ���ɾ�������ļ�����־�ļ�
     *
     * @param key
     * @return �Ƿ�ɾ��������
     * @throws IOException
     */
    private boolean innerRemove(final byte[] key, final boolean sync) throws IOException {
        boolean ret = false;
        final BytesKey k = new BytesKey(key);
        final OpItem op = this.indices.get(k);
        if (null != op) {
            ret = this.innerRemove(op, k, sync);
            if (ret) {
                this.indices.remove(k);
                this.lastModifiedMap.remove(k);
            }
        }
        return ret;
    }


    /**
     * ����OpItem��������־�ļ��м�¼ɾ���IJ�����־�������޸Ķ�Ӧ�����ļ������ü���.
     *
     * @param op
     * @return
     * @throws IOException
     */
    private boolean innerRemove(final OpItem op, final BytesKey bytesKey, final boolean sync) throws IOException {
        final DataFile df = this.dataFiles.get(Integer.valueOf(op.number));
        final LogFile lf = this.logFiles.get(Integer.valueOf(op.number));
        if (null != df && null != lf) {
            final OpItem o = new OpItem();
            o.key = op.key;
            o.length = op.length;
            o.number = op.number;
            o.offset = op.offset;
            o.op = OpItem.OP_DEL;
            this.dataFileAppender.remove(o, bytesKey, sync);
            return true;
        }
        return false;
    }


    /**
     * �������Ƿ�Ϸ�
     *
     * @param key
     * @param data
     */
    private void checkParam(final byte[] key, final byte[] data) {
        if (null == key || null == data) {
            throw new NullPointerException("key/data can't be null");
        }
        if (key.length != 16) {
            throw new IllegalArgumentException("key.length must be 16");
        }
    }


    /**
     * ����һ���µ������ļ�
     *
     * @throws FileNotFoundException
     */
    protected DataFile newDataFile() throws IOException {
        if (this.dataFiles.size() > this.maxFileCount) {
            throw new RuntimeException("���ֻ�ܴ洢" + this.maxFileCount + "�������ļ�");
        }
        final int n = this.number.incrementAndGet();
        this.dataFile = new DataFile(new File(this.path + File.separator + this.name + "." + n), n, this.force);
        this.logFile = new LogFile(new File(this.path + File.separator + this.name + "." + n + ".log"), n, this.force);
        this.dataFiles.put(Integer.valueOf(n), this.dataFile);
        this.logFiles.put(Integer.valueOf(n), this.logFile);
        log.info("�������ļ���" + this.dataFile);
        return this.dataFile;
    }


    /**
     * Create the parent directory if it doesn't exist.
     */
    private void checkParentDir(final File parent) {
        if (!parent.exists() && !parent.mkdirs()) {
            throw new IllegalStateException("Can't make dir " + this.path);
        }
    }


    /**
     * ���ʼ����ʱ����Ҫ�������е���־�ļ����ָ��ڴ������
     *
     * @throws IOException
     */
    private void initLoad() throws IOException {
        log.warn("��ʼ�ָ�����");
        final String nm = this.name + ".";
        final File dir = new File(this.path);
        this.checkParentDir(dir);
        final File[] fs = dir.listFiles(new FilenameFilter() {
            @Override
            public boolean accept(final File dir, final String n) {
                return n.startsWith(nm) && !n.endsWith(".log");
            }
        });
        if (fs == null || fs.length == 0) {
            return;
        }
        log.warn("����ÿ�������ļ�");
        final List<Integer> indexList = new LinkedList<Integer>();
        for (final File f : fs) {
            try {
                final String fn = f.getName();
                final int n = Integer.parseInt(fn.substring(nm.length()));
                indexList.add(Integer.valueOf(n));
            }
            catch (final Exception e) {
                log.error("parse file index error" + f, e);
            }
        }

        Integer[] indices = indexList.toArray(new Integer[indexList.size()]);

        // ���ļ�˳���������
        Arrays.sort(indices);

        for (final Integer n : indices) {
            log.warn("����indexΪ" + n + "���ļ�");
            // ���汾�����ļ���������Ϣ
            final Map<BytesKey, OpItem> idx = new HashMap<BytesKey, OpItem>();
            // ����dataFile��logFile
            final File f = new File(dir, this.name + "." + n);
            final DataFile df = new DataFile(f, n, this.force);
            final LogFile lf = new LogFile(new File(f.getAbsolutePath() + ".log"), n, this.force);
            final long size = lf.getLength() / OpItem.LENGTH;

            for (int i = 0; i < size; ++i) { // ѭ��ÿһ������
                final ByteBuffer bf = ByteBuffer.wrap(new byte[OpItem.LENGTH]);
                lf.read(bf, i * OpItem.LENGTH);
                if (bf.hasRemaining()) {
                    log.warn("log file error:" + lf + ", index:" + i);
                    continue;
                }
                final OpItem op = new OpItem();
                op.parse(bf.array());
                final BytesKey key = new BytesKey(op.key);
                switch (op.op) {
                case OpItem.OP_ADD: // �������ӵIJ����������������������ü���
                    final OpItem o = this.indices.get(key);
                    if (null != o) {
                        // �Ѿ���֮ǰ��ӹ�����ô��Ȼ��Update��ʱ��Remove�IJ�����־û��д�롣

                        // д��Remove��־
                        this.innerRemove(o, key, true);

                        // ��map��ɾ��
                        this.indices.remove(key);
                        this.lastModifiedMap.remove(key);
                    }
                    boolean addRefCount = true;
                    if (idx.get(key) != null) {
                        // ��ͬһ���ļ���add����update������ôֻ�Ǹ������ݣ������������ü�����
                        addRefCount = false;
                    }

                    idx.put(key, op);

                    if (addRefCount) {
                        df.increment();
                    }
                    break;

                case OpItem.OP_DEL: // �����ɾ���IJ���������ȥ�����������ü���
                    idx.remove(key);
                    df.decrement();
                    break;

                default:
                    log.warn("unknow op:" + (int) op.op);
                    break;
                }
            }
            if (df.getLength() >= FILE_SIZE && df.isUnUsed()) { // �����������ļ��Ѿ��ﵽָ����С�����Ҳ���ʹ�ã�ɾ��
                df.delete();
                lf.delete();
                log.warn("�����ˣ�Ҳ�����˴�С��ɾ��");
            }
            else { // �������map
                this.dataFiles.put(n, df);
                this.logFiles.put(n, lf);
                if (!df.isUnUsed()) { // ���������������������
                    this.indices.putAll(idx);
                    // ��������������־�ļ�������޸�ʱ��,����û�б�Ҫ�dz���ȷ.
                    final long lastModified = lf.lastModified();
                    for (final BytesKey key : idx.keySet()) {
                        this.lastModifiedMap.put(key, lastModified);
                    }
                    log.warn("����ʹ�ã�����������referenceCount:" + df.getReferenceCount() + ", index:" + idx.size());
                }
            }
        }
        // У����ص��ļ��������õ�ǰ�ļ�
        if (this.dataFiles.size() > 0) {
            indices = this.dataFiles.keySet().toArray(new Integer[this.dataFiles.keySet().size()]);
            Arrays.sort(indices);
            for (int i = 0; i < indices.length - 1; i++) {
                final DataFile df = this.dataFiles.get(indices[i]);
                if (df.isUnUsed() || df.getLength() < FILE_SIZE) {
                    throw new IllegalStateException("�ǵ�ǰ�ļ���״̬�Ǵ��ڵ����ļ��鳤�ȣ�������used״̬");
                }
            }
            final Integer n = indices[indices.length - 1];
            this.number.set(n.intValue());
            this.dataFile = this.dataFiles.get(n);
            this.logFile = this.logFiles.get(n);
        }
        log.warn("�ָ����ݣ�" + this.size());
    }


    /*
     * (non-Javadoc)
     *
     * @see com.taobao.common.store.Store#size()
     */
    @Override
    public int size() {
        return this.indices.size();
    }


    /*
     * (non-Javadoc)
     *
     * @see com.taobao.common.store.Store#update(byte[], byte[])
     */
    @Override
    public boolean update(final byte[] key, final byte[] data) throws IOException {
        // ����Update����Ϣ������д��OpCodeΪUpdate����־��
        final BytesKey k = new BytesKey(key);
        final OpItem op = this.indices.get(k);
        if (null != op) {
            this.indices.remove(k);
            final OpItem o = this.innerAdd(key, data, -1, false);
            if (o.number != op.number) {
                // ����ͬһ���ļ��ϸ��£��Ž���ɾ����
                this.innerRemove(op, k, false);
            }
            else {
                // ͬһ���ļ��ϸ��£�����DataFile���ã���Ϊadd��ʱ������
                final DataFile df = this.dataFiles.get(Integer.valueOf(op.number));
                df.decrement();
            }
            return true;
        }
        return false;
    }


    /*
     * (non-Javadoc)
     *
     * @see com.taobao.common.store.journal.JournalStoreMBean#getDataFilesInfo()
     */
    @Override
    public String getDataFilesInfo() {
        return this.dataFiles.toString();
    }


    /*
     * (non-Javadoc)
     *
     * @see com.taobao.common.store.journal.JournalStoreMBean#getLogFilesInfo()
     */
    @Override
    public String getLogFilesInfo() {
        return this.logFiles.toString();
    }


    /*
     * (non-Javadoc)
     *
     * @see com.taobao.common.store.journal.JournalStoreMBean#getNumber()
     */
    @Override
    public int getNumber() {
        return this.number.get();
    }


    /*
     * (non-Javadoc)
     *
     * @see com.taobao.common.store.journal.JournalStoreMBean#getPath()
     */
    @Override
    public String getPath() {
        return this.path;
    }


    /*
     * (non-Javadoc)
     *
     * @see com.taobao.common.store.journal.JournalStoreMBean#getName()
     */
    @Override
    public String getName() {
        return this.name;
    }


    /*
     * (non-Javadoc)
     *
     * @see com.taobao.common.store.journal.JournalStoreMBean#getDataFileInfo()
     */
    @Override
    public String getDataFileInfo() {
        return this.dataFile.toString();
    }


    /*
     * (non-Javadoc)
     *
     * @see com.taobao.common.store.journal.JournalStoreMBean#getLogFileInfo()
     */
    @Override
    public String getLogFileInfo() {
        return this.logFile.toString();
    }


    /*
     * (non-Javadoc)
     *
     * @see com.taobao.common.store.journal.JournalStoreMBean#viewIndexMap()
     */
    @Override
    public String viewIndexMap() {
        return this.indices.toString();
    }


    /*
     * (non-Javadoc)
     *
     * @see com.taobao.common.store.Store#close()
     */
    @Override
    public void close() throws IOException {
        this.sync();
        for (final DataFile df : this.dataFiles.values()) {
            try {
                df.close();
            }
            catch (final Exception e) {
                log.warn("close error:" + df, e);
            }
        }
        this.dataFiles.clear();
        for (final LogFile lf : this.logFiles.values()) {
            try {
                lf.close();
            }
            catch (final Exception e) {
                log.warn("close error:" + lf, e);
            }
        }
        this.logFiles.clear();
        this.indices.close();
        this.lastModifiedMap.clear();
        this.dataFile = null;
        this.logFile = null;
    }


    /*
     * (non-Javadoc)
     *
     * @see com.taobao.common.store.journal.JournalStoreMBean#getSize()
     */
    @Override
    public long getSize() throws IOException {
        return this.size();
    }


    @Override
    public long getIntervalForCompact() {
        return this.intervalForCompact;
    }


    @Override
    public void setIntervalForCompact(final long intervalForCompact) {
        this.intervalForCompact = intervalForCompact;
    }


    @Override
    public long getIntervalForRemove() {
        return this.intervalForRemove;
    }


    @Override
    public void setIntervalForRemove(final long intervalForRemove) {
        this.intervalForRemove = intervalForRemove;
    }


    @Override
    public long getMaxFileCount() {
        return this.maxFileCount;
    }


    @Override
    public void setMaxFileCount(final long maxFileCount) {
        this.maxFileCount = maxFileCount;
    }


    public void sync() {
        this.dataFileAppender.sync();
    }


    /**
     * �������ļ����м�飬��������Ӧ�Ĵ���
     *
     * 1.���ݳ���ָ����Removeʱ��,����ֱ��ɾ�� 2.���ݳ���ָ����Compactʱ�䣬��Remove��Add
     *
     * @throws IOException
     */
    @Override
    public void check() throws IOException {
        final Iterator<byte[]> keys = this.iterator();
        BytesKey key = null;
        final long now = System.currentTimeMillis();
        long time;
        log.warn("Store4j�����ļ�����ʼ...");
        while (keys.hasNext()) {
            key = new BytesKey(keys.next());
            time = this.lastModifiedMap.get(key);
            if (this.intervalForRemove != -1 && now - time > this.intervalForRemove) {
                this.innerRemove(key.getData(), true);
            }
            else if (now - time > this.intervalForCompact) {
                this.reuse(key.getData(), true);
            }
        }
        log.warn("Store4j�����ļ��������...");
    }

    /**
     * �����ļ����ĺ�̨�̣߳���ҪĿ����Ϊ��Store4j�����ļ��������Ĺ������£�
     */
    class DataFileCheckThread implements Runnable {

        @Override
        public void run() {
            try {
                JournalStore.this.check();
            }
            catch (final Exception ex) {
                log.warn("check error:", ex);
            }
        }
    }
}
TOP

Related Classes of com.taobao.common.store.journal.JournalStore$InflyWriteData

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
d', 'pageview');