All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gs.fw.common.mithra.finder.MultiEqualityMapper Maven / Gradle / Ivy

There is a newer version: 18.1.0
Show newest version
/*
 Copyright 2016 Goldman Sachs.
 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.gs.fw.common.mithra.finder;

import java.util.*;

import com.gs.collections.impl.list.mutable.FastList;
import com.gs.collections.impl.set.mutable.UnifiedSet;
import com.gs.fw.common.mithra.MithraObjectPortal;
import com.gs.fw.common.mithra.attribute.AsOfAttribute;
import com.gs.fw.common.mithra.attribute.Attribute;
import com.gs.fw.common.mithra.attribute.MappedAttribute;
import com.gs.fw.common.mithra.attribute.TupleAttribute;
import com.gs.fw.common.mithra.cache.Cache;
import com.gs.fw.common.mithra.cache.ConcurrentFullUniqueIndex;
import com.gs.fw.common.mithra.cache.IndexReference;
import com.gs.fw.common.mithra.extractor.Extractor;
import com.gs.fw.common.mithra.finder.asofop.AsOfEqOperation;
import com.gs.fw.common.mithra.notification.MithraDatabaseIdentifierExtractor;
import com.gs.fw.common.mithra.util.InternalList;
import com.gs.fw.common.mithra.util.ListFactory;
import com.gs.fw.common.mithra.util.MithraFastList;
import com.gs.reladomo.metadata.PrivateReladomoClassMetaData;


public class MultiEqualityMapper extends AbstractMapper
{

    private InternalList equalityMappers;
    private Attribute[] leftAttributes;
    private transient IndexReference bestIndexRef;
    private int mappedIndex = -1;

    public MultiEqualityMapper(Attribute left, Attribute right)
    {
        initialize(2);
        this.addEqualityMapper(left.constructEqualityMapper(right));
    }

    public MultiEqualityMapper(MultiEqualityMapper source, EqualityMapper newMapper)
    {
        initialize(source.equalityMappers.size()+1);
        this.addEqualityMappers(source.equalityMappers);
        this.addEqualityMapper(newMapper);
    }

    private void initialize(int size)
    {
        this.equalityMappers = new InternalList(size);
        this.leftAttributes = new Attribute[size];
    }

    public MultiEqualityMapper(MultiEqualityMapper source1, MultiEqualityMapper source2)
    {
        initialize(source1.equalityMappers.size()+source2.equalityMappers.size());
        this.addEqualityMappers(source1.equalityMappers);
        for(int i=0;i=0)
                {
                    this.equalityMappers.swap(mappedIndex, i);
                    mappedIndex++;
                }
            }
        }
    }

    protected MultiEqualityMapper(InternalList equalityMappers, Mapper reverseMapper)
    {
        this(equalityMappers);
        this.reverseMapper = reverseMapper;
    }

    public void addAutoGeneratedAttributeMap(Attribute left, Attribute right)
    {
        EqualityMapper equalityMapper = left.constructEqualityMapper(right);
        equalityMapper.setAutoGenerated(true);
        this.addEqualityMapper(equalityMapper);
    }

    private void addEqualityMapper(EqualityMapper mapper)
    {
        if (!equalityMappers.contains(mapper))
        {
            Attribute left = mapper.getLeft();
            if (left instanceof MappedAttribute)
            {
                addToLeftAttributes(left);
                this.equalityMappers.add(mapper);
                if (mappedIndex < 0)
                {
                    mappedIndex = this.equalityMappers.size() - 1;
                }
            }
            else
            {
                if (mappedIndex >=0)
                {
                    insertIntoArray(this.leftAttributes, mappedIndex, left);
                    this.equalityMappers.add(mappedIndex, mapper);
                    mappedIndex++;
                }
                else
                {
                    addToLeftAttributes(left);
                    this.equalityMappers.add(mapper);
                }
            }
        }
    }

    private void addToLeftAttributes(Attribute left)
    {
        if (this.leftAttributes.length <= this.equalityMappers.size())
        {
            Attribute[] tmp = this.leftAttributes;
            this.leftAttributes = new Attribute[this.equalityMappers.size() + 1];
            System.arraycopy(tmp, 0, this.leftAttributes, 0, tmp.length);
        }
        this.leftAttributes[this.equalityMappers.size()] = left;
    }

    private void insertIntoArray(Attribute[] leftAttributes, int index, Attribute left)
    {
        System.arraycopy(leftAttributes, index, leftAttributes, index + 1, leftAttributes.length - index - 1);
        leftAttributes[index] = left;
    }

    private void addEqualityMappers(InternalList mappers)
    {
        for(int i=0;i 0 && cache.isUnique(indexRef);
    }

    public boolean mapUsesImmutableUniqueIndex()
    {
        Cache cache = this.getCache();
        int indexRef = this.getBestIndexRef(cache);
        return indexRef > 0 && cache.isUniqueAndImmutable(indexRef);
    }

    public boolean mapUsesNonUniqueIndex()
    {
        Cache cache = this.getCache();
        int indexRef = this.getBestIndexRef(cache);
        return indexRef > 0 && indexRef != IndexReference.AS_OF_PROXY_INDEX_ID && !cache.isUnique(indexRef);
    }

    public List map(List joinedList)
    {
        return getResultViaMultiIn(joinedList, null);
    }

    public ConcurrentFullUniqueIndex mapMinusOneLevel(List joinedList)
    {
        Extractor[] extractors = new Extractor[this.equalityMappers.size()];
        for(int i=0;i 1)
                {
                    return null;
                }
                needsInClause[leftIndex] = true;
                if (firstNonConstantAttribute == null)
                {
                    firstNonConstantAttribute = right;
                }
                else if (tupleAttribute == null)
                {
                    tupleAttribute = firstNonConstantAttribute.tupleWith(right);
                }
                else
                {
                    tupleAttribute = tupleAttribute.tupleWith(right);
                }
            }
        }
        if (inClauseCount == 0) return constants;
        if (tupleAttribute != null)
        {
            Extractor[] extractors = new Extractor[inClauseCount];
            int count = 0;
            for(int i=0;i tempOperationPool)
    {
        AtomicOperation[] ops = new AtomicOperation[this.equalityMappers.size()];
        for(int i=0;i tempOperationPool)
    {
        AtomicOperation[] ops = new AtomicOperation[this.equalityMappers.size()];
        for(int i=0;i tempOperationPool)
    {
        AtomicOperation[] ops = new AtomicOperation[this.equalityMappers.size()];
        for(int i=0;i getUnChainedMappers()
    {
        return ListFactory.create(this);
    }

    public boolean hasLeftOrDefaultMappingsFor(AsOfAttribute[] leftAsOfAttributes)
    {
        int count = 0;
        fixLeftAttributes();
        for(int j=0;j getAllLeftAttributes()
    {
        fixLeftAttributes();
        UnifiedSet result = new UnifiedSet(this.leftAttributes.length);
        for(int i=0;i attributeMap, Object prototypeObject, int chainPosition)
    {
        Operation op = NoOperation.instance();
        InternalList newMappers = new InternalList(this.equalityMappers.size());
        for(int i=0;i attributeMap)
    {
        for(int i=0;i 0)
        {
            return this.getCache().getAverageReturnSize(indexRef, 1);
        }
        else
        {
            double leftSize = this.getAnyLeftAttribute().getOwnerPortal().getCache().estimateQuerySize();
            double rightSize = this.getAnyRightAttribute().getOwnerPortal().getCache().estimateQuerySize();
            if (rightSize == 0) return 0;
            return leftSize / rightSize;
        }
    }

    @Override
    public int estimateMaxReturnSize(int multiplier)
    {
        int indexRef = this.getBestIndexRef(this.getCache());
        if (indexRef > 0)
        {
            return this.getCache().getMaxReturnSize(indexRef, multiplier);
        }
        else
        {
            double leftSize = this.getAnyLeftAttribute().getOwnerPortal().getCache().estimateQuerySize();
            double rightSize = this.getAnyRightAttribute().getOwnerPortal().getCache().estimateQuerySize();
            if (rightSize == 0) return 0;
            return (int) Math.min(leftSize  * multiplier/ rightSize, this.getCache().estimateQuerySize());
        }
    }

    private boolean hasRightAttribute(AsOfAttribute asOfAttribute)
    {
        for(int i=0;i=0) return getAndOperation(target);
        return getMultiEqualityOperationForSize(target, this.equalityMappers.size());
    }

    private Operation getMultiEqualityOperationForSize(Object target, int size)
    {
        AtomicOperation[] newOperations = new AtomicOperation[size];
        for(int i=0;i< size;i++)
        {
            EqualityMapper mapper = ((EqualityMapper)this.equalityMappers.get(i));
            Attribute right = mapper.getRight();
            if (right.isAttributeNull(target))
            {
                return new None(mapper.getLeft());
            }
            newOperations[i] = (AtomicOperation) mapper.getLeft().nonPrimitiveEq(right.valueOf(target));
        }
        return new MultiEqualityOperation(newOperations);
    }

    private Operation getAndOperation(Object target)
    {
        Operation first = getMultiEqualityOperationForSize(target, this.mappedIndex);
        Operation second = NoOperation.instance();
        for(int i=this.mappedIndex;i< this.equalityMappers.size();i++)
        {
            EqualityMapper mapper = ((EqualityMapper)this.equalityMappers.get(i));
            Attribute right = mapper.getRight();
            if (right.isAttributeNull(target))
            {
                return new None(mapper.getLeft());
            }
            second = second.and(mapper.getLeft().nonPrimitiveEq(right.valueOf(target)));
        }
        return first.and(second);
    }

    public void generateSql(SqlQuery query)
    {
        boolean mappedAlready = query.isMappedAlready(this);
        String[] leftArray = null;
        if (!mappedAlready)
        {
            leftArray = new String[this.equalityMappers.size()];
            for(int i=0;i ");
        stringBuilder.append(this.getFromPortal().getBusinessClassName()).append(": ");
        for(int i=0;i 0) stringBuilder.append(" & ");
            EqualityMapper equalityMapper = ((EqualityMapper)this.equalityMappers.get(i));
            equalityMapper.appendEquality(stringBuilder);
        }
        stringBuilder.append(" ]");
    }

    public boolean isSingleLevelJoin()
    {
        for(int i=0;i ignore)
    {
        AsOfAttribute[] asOfAttributes = ((PrivateReladomoClassMetaData)this.getFromPortal().getClassMetaData()).getCachedAsOfAttributes();
        InternalList results = null;
        if (asOfAttributes != null)
        {
            for(int i=0;i parentObjects, EqualityOperation extraEqOp, Operation extraOperation)
    {
        MithraFastList attrList = new MithraFastList(this.equalityMappers.size() + 2);
        for(int i=0;i extractors = new MithraFastList(indexAttributes.length);
            Operation localExtraOperation = extraOperation;
            if (indexAttributes.length != attrList.size())
            {
                localExtraOperation = localExtraOperation == null ? extraEqOp : extraEqOp.and(localExtraOperation);
            }
            int eqMapperCount = 0;
            for(Attribute a: indexAttributes)
            {
                EqualityMapper eqMapper = getEqualitMapperFor(a);
                if (eqMapper != null)
                {
                    extractors.add(eqMapper.getLeft());
                    eqMapperCount++;
                }
                else
                {
                    extractors.add(extraEqOp.getParameterExtractorFor(a));
                }
            }
            List leftOverExtractors = null;
            if (eqMapperCount != this.equalityMappers.size())
            {
                leftOverExtractors = new MithraFastList(this.equalityMappers.size() - eqMapperCount);
                for(int i=0;i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy