cosmos.sql.impl.LogicVisitor.java Source code

Java tutorial

Introduction

Here is the source code for cosmos.sql.impl.LogicVisitor.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with this
 * work for additional information regarding copyright ownership. The ASF
 * licenses this file to you 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.
 *
 *  Copyright 2013 
 *
 */
package cosmos.sql.impl;

import java.util.Collections;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;

import org.apache.accumulo.core.client.MutationsRejectedException;
import org.apache.accumulo.core.client.TableNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Function;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.RemovalListener;
import com.google.common.cache.RemovalNotification;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.hash.HashCode;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;

import cosmos.Cosmos;
import cosmos.UnexpectedStateException;
import cosmos.UnindexedColumnException;
import cosmos.records.impl.MultimapRecord;
import cosmos.results.Column;
import cosmos.sql.call.ChildVisitor;
import cosmos.sql.call.Field;
import cosmos.sql.call.Literal;
import cosmos.sql.call.Pair;
import cosmos.sql.call.impl.FieldEquality;
import cosmos.sql.call.impl.operators.AndOperator;
import cosmos.sql.call.impl.operators.OrOperator;
import cosmos.store.Store;

public class LogicVisitor implements Function<ChildVisitor, Iterable<MultimapRecord>> {

    private Store sortRes;
    private Cosmos cosmosRef;

    private static final Logger log = LoggerFactory.getLogger(LogicVisitor.class);

    protected static final Cache<String, Entry<Cosmos, Store>> tempTableCache;

    static {

        RemovalListener<String, Entry<Cosmos, Store>> removalListener = new RemovalListener<String, Entry<Cosmos, Store>>() {
            public void onRemoval(RemovalNotification<String, Entry<Cosmos, Store>> removal) {
                Entry<Cosmos, Store> entry = removal.getValue();

                try {
                    entry.getKey().delete(entry.getValue());
                } catch (MutationsRejectedException e) {
                    log.error("Could not delete", e);
                } catch (TableNotFoundException e) {
                    log.error("Could not delete", e);
                } catch (UnexpectedStateException e) {
                    log.error("Could not delete", e);
                }

            }
        };
        tempTableCache = CacheBuilder.newBuilder().expireAfterAccess(2, TimeUnit.HOURS)
                .removalListener(removalListener).build();
    }

    public LogicVisitor(Cosmos cosmos, Store res) {
        this.sortRes = res;
        this.cosmosRef = cosmos;
    }

    @Override
    public Iterable<MultimapRecord> apply(ChildVisitor input) {

        HashFunction hf = Hashing.md5();
        HashCode hc = hf.newHasher().putObject(input, input).hash();

        Entry<Cosmos, Store> entry = tempTableCache.getIfPresent(hc.toString());

        if (null != entry) {

            try {
                return entry.getKey().fetch(entry.getValue());
            } catch (TableNotFoundException e) {
                log.error("Could not fetch results", e);
            } catch (UnexpectedStateException e) {
                log.error("Could not fetch results", e);
            }
        }

        Iterable<MultimapRecord> iter = Collections.emptyList();
        if (input instanceof FieldEquality) {
            FieldEquality equality = (FieldEquality) input;
            iter = apply(equality);
        } else if (input instanceof AndOperator) {
            AndOperator andOp = (AndOperator) input;
            iter = apply(andOp);

        } else if (input instanceof OrOperator) {
            OrOperator orOp = (OrOperator) input;

            iter = apply(orOp);
        }

        return iter;
    }

    protected Iterable<MultimapRecord> apply(AndOperator andOp) {

        Iterable<MultimapRecord> iter = Collections.emptyList();
        Iterable<ChildVisitor> children = Iterables.filter(andOp.getChildren(), new FilterFilter());
        Iterator<ChildVisitor> childIter = children.iterator();
        if (childIter.hasNext()) {
            iter = apply((FieldEquality) childIter.next());
        }

        while (childIter.hasNext()) {
            FieldEquality equality = (FieldEquality) childIter.next();
            for (ChildVisitor child : equality.getChildren()) {
                @SuppressWarnings("unchecked")
                Pair<Field, Literal> entry = (Pair<Field, Literal>) child;
                iter = Iterables.filter(iter,
                        new DocumentFieldPredicate((Field) entry.first(), (Literal) entry.second()));
            }

        }

        return iter;
    }

    protected Iterable<MultimapRecord> apply(OrOperator andOp) {

        Iterable<MultimapRecord> iter = Collections.emptyList();
        Iterable<ChildVisitor> children = Iterables.filter(andOp.getChildren(), new FilterFilter());
        Iterator<ChildVisitor> childIter = children.iterator();

        while (childIter.hasNext()) {
            FieldEquality equality = (FieldEquality) childIter.next();

            iter = Iterables.concat(iter, apply(equality));

        }

        Store meatadata = new Store(sortRes.connector(), sortRes.auths(), sortRes.columnsToIndex());

        try {
            cosmosRef.register(meatadata);
            cosmosRef.addResults(meatadata, iter);
            iter = Collections.emptyList();

            HashFunction hf = Hashing.md5();
            HashCode hc = hf.newHasher().putObject(andOp, andOp).hash();

            tempTableCache.put(hc.toString(), Maps.immutableEntry(cosmosRef, meatadata));

            return cosmosRef.fetch(meatadata);
        } catch (Exception e) {
            log.error("Could not fetch results", e);
        }

        return iter;
    }

    @SuppressWarnings("unchecked")
    protected Iterable<MultimapRecord> apply(FieldEquality equality) {
        Iterable<MultimapRecord> iter = Collections.emptyList();
        for (ChildVisitor child : equality.getChildren()) {
            Pair<Field, Literal> entry = (Pair<Field, Literal>) child;
            cosmos.sql.call.Field field = (Field) entry.first();
            cosmos.sql.call.Literal literal = (Literal) entry.second();
            try {
                iter = Iterables.concat(cosmosRef.fetch(sortRes, new Column(field.toString()), literal.toString()));
            } catch (TableNotFoundException e) {
                log.error("Could not fetch results", e);
            } catch (UnexpectedStateException e) {
                log.error("Could not fetch results", e);
            } catch (UnindexedColumnException e) {
                log.error("Could not fetch results", e);
            }
        }
        return iter;

    }

}