Package com.foundationdb.server.service.tree

Source Code of com.foundationdb.server.service.tree.TreeServiceExchangeCacheIT

/**
* Copyright (C) 2009-2013 FoundationDB, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.foundationdb.server.service.tree;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import com.foundationdb.ais.model.AkibanInformationSchema;
import com.foundationdb.ais.model.HasStorage;
import com.foundationdb.ais.model.TableName;
import com.foundationdb.server.store.format.PersistitStorageDescription;
import com.foundationdb.server.test.it.PersistitITBase;
import org.junit.Before;
import org.junit.Test;

import com.persistit.Exchange;
import com.persistit.Tree;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TreeServiceExchangeCacheIT extends PersistitITBase
{
    private static final int MAX_TREE_CACHE = 6;
    private static final int MAX_EXCHANGE_CACHE = 3;

    private TreeServiceImpl treeService;

    private static final String identifier = "test";

    @Before
    public void setTreeService() {
        treeService = (TreeServiceImpl)treeService();
    }

    @Override
    protected Map<String, String> startupConfigProperties() {
        Map<String,String> props = new HashMap<>( super.startupConfigProperties() );
        props.put(TreeServiceImpl.MAX_TREE_CACHE_PROP_NAME, Integer.toString(MAX_TREE_CACHE));
        props.put(TreeServiceImpl.MAX_EXCHANGE_CACHE_PROP_NAME, Integer.toString(MAX_EXCHANGE_CACHE));
        return props;
    }


    /**
     * Tree being removed will cause cache clear on release.
     * However, Trees aren't normally removed as they are non-transactional in < Persistit 3.3.0.
     */
    @Test
    public void invalidTreeClearsCache() throws Exception {
        final Exchange ex1 = treeService.getExchange(session(), new TestLink("schema", "someTree"));
        final Tree tree = ex1.getTree();
        treeService.releaseExchange(session(), ex1);
        assertFalse(treeService.exchangeQueue(session(), ex1.getTree()).isEmpty());
        final Exchange ex2 = treeService.getExchange(session(), new TestLink("schema", "someTree"));
        final Exchange ex3 = treeService.getExchange(session(), new TestLink("schema", "someTree"));
        treeService.releaseExchange(session(), ex3);
        assertEquals("cached exchange count", 1, getCachedExchangeCount(tree));
        ex2.removeTree();
        treeService.releaseExchange(session(), ex2);
        assertEquals("cached exchange queue", null, treeService.exchangeQueue(session(), tree));
    }

    /** As {@link #invalidTreeClearsCache} but Store level removal also busts cache. */
    @Test
    public void storeRemoveTreeClearsCache() {
        PersistitStorageDescription desc = createDescription("tree");
        final Exchange ex1 = treeService.getExchange(session(), desc);
        final Exchange ex2 = treeService.getExchange(session(), desc);
        treeService.releaseExchange(session(), ex1);
        treeService.releaseExchange(session(), ex2);
        assertEquals("cached exchange count", 2, getCachedExchangeCount(ex1.getTree()));
        store().removeTree(session(), desc.getObject());
        assertEquals("cached exchange count", 0, getCachedExchangeCount(ex1.getTree()));
    }

    @Test
    public void maxTreeCache() {
        for(int i = 0; i < (MAX_EXCHANGE_CACHE * 5); ++i) {
            PersistitStorageDescription desc = createDescription("tree_" + i);
            Exchange ex = treeService.getExchange(session(), desc);
            treeService.releaseExchange(session(), ex);
        }
        assertEquals("cached tree count", MAX_TREE_CACHE, treeService.getCachedTreeCount(session()));
    }

    @Test
    public void maxExchangeCache() {
        PersistitStorageDescription desc = createDescription("tree");
        List<Exchange> exchanges = new ArrayList<>();
        for(int i = 0; i < (MAX_EXCHANGE_CACHE * 5); ++i) {
            exchanges.add(treeService.getExchange(session(), desc));
        }
        Tree tree = exchanges.get(0).getTree();
        for(Exchange ex : exchanges) {
            treeService.releaseExchange(session(), ex);
        }
        assertEquals("cached exchange count", MAX_EXCHANGE_CACHE, getCachedExchangeCount(tree));
    }

    @Test
    public void manyTablesTest() {
        for(int i = 0; i < 50; ++i) {
            TableName name = new TableName("test", "t_"+i);
            int tid = createTable(name, "id int not null primary key");
            expectRows(tid);
            expectRows(getTable(tid).getPrimaryKey().getIndex());
            ddl().dropTable(session(), name);
        }
        // A little slop for internal trees (e.g. schema manager, index statistics)
        int count = treeService.getCachedTreeCount(session());
        assertTrue("cached tree count: " + count, count < 5);
    }


    private int getCachedExchangeCount(Tree tree) {
        return treeService.exchangeQueue(session(), tree).size();
    }

    private PersistitStorageDescription createDescription(String treeName) {
        PersistitStorageDescription desc = new PersistitStorageDescription(new TestStorage(ais(), "test", treeName), treeName, identifier);
        desc.getObject().setStorageDescription(desc);
        return desc;
    }

    private static class TestStorage extends HasStorage {
        private final AkibanInformationSchema ais;
        private final String schema;
        private final String tree;

        private TestStorage(AkibanInformationSchema ais, String schema, String tree) {
            this.ais = ais;
            this.schema = schema;
            this.tree = tree;
        }

        @Override
        public AkibanInformationSchema getAIS() {
            return ais;
        }

        @Override
        public String getTypeString() {
            return getClass().getSimpleName();
        }

        @Override
        public String getNameString() {
            return tree;
        }

        @Override
        public String getSchemaName() {
            return schema;
        }
    }
}
TOP

Related Classes of com.foundationdb.server.service.tree.TreeServiceExchangeCacheIT

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.