Package org.teiid.query.tempdata

Source Code of org.teiid.query.tempdata.TempTableStore

/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.  Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/

package org.teiid.query.tempdata;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.api.exception.query.QueryProcessingException;
import org.teiid.api.exception.query.QueryResolverException;
import org.teiid.api.exception.query.QueryValidatorException;
import org.teiid.common.buffer.BufferManager;
import org.teiid.core.TeiidComponentException;
import org.teiid.language.SQLConstants;
import org.teiid.query.QueryPlugin;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.metadata.TempMetadataID;
import org.teiid.query.metadata.TempMetadataStore;
import org.teiid.query.optimizer.relational.RelationalPlanner;
import org.teiid.query.resolver.QueryResolver;
import org.teiid.query.resolver.command.TempTableResolver;
import org.teiid.query.resolver.util.ResolverUtil;
import org.teiid.query.sql.lang.CacheHint;
import org.teiid.query.sql.lang.Command;
import org.teiid.query.sql.lang.Create;
import org.teiid.query.sql.lang.Insert;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.GroupSymbol;

public class TempTableStore {
 
  public enum MatState {
    NEEDS_LOADING,
    LOADING,
    FAILED_LOAD,
    LOADED
  }
 
  public static class MatTableInfo {
    private long updateTime = -1;
    private MatState state = MatState.NEEDS_LOADING;
    private long ttl = -1;
    private boolean valid;
   
    synchronized boolean shouldLoad() throws TeiidComponentException {
        for (;;) {
      switch (state) {
      case NEEDS_LOADING:
      case FAILED_LOAD:
        setState(MatState.LOADING);
        return true;
      case LOADING:
        if (valid) {
          return false;
        }
        try {
          wait();
        } catch (InterruptedException e) {
          throw new TeiidComponentException(e);
        }
        continue;
      case LOADED:
        if (ttl >= 0 && System.currentTimeMillis() - updateTime - ttl > 0) {
          setState(MatState.LOADING);
          return true;
        }
        return false;
      }
        }
    }
   
    public synchronized MatState setState(MatState state, Boolean valid, Long timestamp) {
      MatState oldState = this.state;
      if (valid != null) {
        this.valid = valid;
      }
      setState(state);
      if (timestamp != null) {
        this.updateTime = timestamp;
      }
      notifyAll();
      return oldState;
    }
   
    private void setState(MatState state) {
      this.state = state;
      this.updateTime = System.currentTimeMillis();
    }
   
    public synchronized void setTtl(long ttl) {
      this.ttl = ttl;
    }
   
    public synchronized long getUpdateTime() {
      return updateTime;
    }
   
    public synchronized MatState getState() {
      return state;
    }
   
    public synchronized boolean isValid() {
      return valid;
    }
   
    public synchronized long getTtl() {
      return ttl;
    }
   
  }
 
  private ConcurrentHashMap<String, MatTableInfo> matTables = new ConcurrentHashMap<String, MatTableInfo>();
 
    private TempMetadataStore tempMetadataStore = new TempMetadataStore(new ConcurrentHashMap<String, TempMetadataID>());
    private Map<String, TempTable> groupToTupleSourceID = new ConcurrentHashMap<String, TempTable>();
    private String sessionID;
    private TempTableStore parentTempTableStore;
   
    public TempTableStore(String sessionID) {
        this.sessionID = sessionID;
    }
   
  public MatTableInfo getMatTableInfo(final String tableName) {
    MatTableInfo newInfo = new MatTableInfo();
    MatTableInfo info = matTables.putIfAbsent(tableName, newInfo);
    if (info == null) {
      info = newInfo;
    }
    return info;
  }
   
    public void setParentTempTableStore(TempTableStore parentTempTableStore) {
    this.parentTempTableStore = parentTempTableStore;
  }
   
    public boolean hasTempTable(String tempTableName) {
      return groupToTupleSourceID.containsKey(tempTableName);
    }

    TempTable addTempTable(String tempTableName, Create create, BufferManager buffer, boolean add) {
      List<ElementSymbol> columns = create.getColumnSymbols();
      TempMetadataID id = tempMetadataStore.getTempGroupID(tempTableName);
      if (id == null) {
          //add metadata
        id = tempMetadataStore.addTempGroup(tempTableName, columns, false, true);
          TempTableResolver.addAdditionalMetadata(create, id);
      }
      columns = new ArrayList<ElementSymbol>(create.getColumnSymbols());
        if (!create.getPrimaryKey().isEmpty()) {
        //reorder the columns to put the key in front
        List<ElementSymbol> primaryKey = create.getPrimaryKey();
        columns.removeAll(primaryKey);
        columns.addAll(0, primaryKey);
      }
        TempTable tempTable = new TempTable(id, buffer, columns, create.getPrimaryKey().size(), sessionID);
        if (add) {
          groupToTupleSourceID.put(tempTableName, tempTable);
        }
        return tempTable;
    }
   
    void swapTempTable(String tempTableName, TempTable tempTable) {
      groupToTupleSourceID.put(tempTableName, tempTable);
    }

    public void removeTempTableByName(String tempTableName) {
        tempMetadataStore.removeTempGroup(tempTableName);
        TempTable table = this.groupToTupleSourceID.remove(tempTableName);
        if(table != null) {
            table.remove();
        }     
    }
   
    public TempMetadataStore getMetadataStore() {
        return tempMetadataStore;
    }
           
    public void removeTempTables() {
        for (String name : groupToTupleSourceID.keySet()) {
            removeTempTableByName(name);
        }
    }
   
    public void setUpdatable(String name, boolean updatable) {
      TempTable table = groupToTupleSourceID.get(name);
      if (table != null) {
        table.setUpdatable(updatable);
      }
    }
   
    TempTable getOrCreateTempTable(String tempTableID, Command command, BufferManager buffer, boolean delegate) throws QueryProcessingException{
      TempTable tsID = groupToTupleSourceID.get(tempTableID);
        if(tsID != null) {
            return tsID;
        }
        if(delegate && this.parentTempTableStore != null){
        tsID = this.parentTempTableStore.groupToTupleSourceID.get(tempTableID);
          if(tsID != null) {
              return tsID;
          }
        }
        //allow implicit temp group definition
        List<ElementSymbol> columns = null;
        if (command instanceof Insert) {
            Insert insert = (Insert)command;
            GroupSymbol group = insert.getGroup();
            if(group.isImplicitTempGroupSymbol()) {
                columns = insert.getVariables();
            }
        }
        if (columns == null) {
          throw new QueryProcessingException(QueryPlugin.Util.getString("TempTableStore.table_doesnt_exist_error", tempTableID)); //$NON-NLS-1$
        }
        Create create = new Create();
        create.setTable(new GroupSymbol(tempTableID));
        create.setElementSymbolsAsColumns(columns);
        return addTempTable(tempTableID, create, buffer, true);      
    }
   
    public Set<String> getAllTempTables() {
        return new HashSet<String>(this.groupToTupleSourceID.keySet());
    }

  public TempMetadataID getGlobalTempTableMetadataId(Object viewId, QueryMetadataInterface metadata)
      throws QueryMetadataException, TeiidComponentException, QueryResolverException, QueryValidatorException {
    String matViewName = metadata.getFullName(viewId);
    String matTableName = RelationalPlanner.MAT_PREFIX+matViewName.toUpperCase();
    GroupSymbol group = new GroupSymbol(matViewName);
    group.setMetadataID(viewId);
    TempMetadataID id = tempMetadataStore.getTempGroupID(matTableName);
    //define the table preserving the key/index information and ensure that only a single instance exists
    if (id == null) {
      synchronized (viewId) {
        id = tempMetadataStore.getTempGroupID(matTableName);
        if (id == null) {
          id = tempMetadataStore.addTempGroup(matTableName, ResolverUtil.resolveElementsInGroup(group, metadata), false, true);
          id.setQueryNode(metadata.getVirtualPlan(viewId));
          id.setCardinality(metadata.getCardinality(viewId));
         
          Object pk = metadata.getPrimaryKey(viewId);
          if (pk != null) {
            ArrayList<TempMetadataID> primaryKey = resolveIndex(metadata, id, pk);
            id.setPrimaryKey(primaryKey);
          }
          Collection keys = metadata.getUniqueKeysInGroup(viewId);
          for (Object key : keys) {
            id.addUniqueKey(resolveIndex(metadata, id, key));
          }
          Collection indexes = metadata.getIndexesInGroup(viewId);
          for (Object index : indexes) {
            id.addIndex(resolveIndex(metadata, id, index));
          }
        }
      }
    }
    updateCacheHint(viewId, metadata, group, id);
    return id;
  }

  private void updateCacheHint(Object viewId,
      QueryMetadataInterface metadata, GroupSymbol group,
      TempMetadataID id) throws TeiidComponentException,
      QueryMetadataException, QueryResolverException,
      QueryValidatorException {
    Command c = QueryResolver.resolveView(group, metadata.getVirtualPlan(viewId), SQLConstants.Reserved.SELECT, metadata).getCommand();
    CacheHint hint = c.getCacheHint();
    id.setCacheHint(hint);
  }
 
  static ArrayList<TempMetadataID> resolveIndex(
      QueryMetadataInterface metadata, TempMetadataID id, Object pk)
      throws TeiidComponentException, QueryMetadataException {
    List cols = metadata.getElementIDsInKey(pk);
    ArrayList<TempMetadataID> primaryKey = new ArrayList<TempMetadataID>(cols.size());
    for (Object coldId : cols) {
      int pos = metadata.getPosition(coldId) - 1;
      primaryKey.add(id.getElements().get(pos));
    }
    return primaryKey;
  }
   
}
TOP

Related Classes of org.teiid.query.tempdata.TempTableStore

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.