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

com.dell.doradus.olap.xlink.XLinkGroupContext Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2014 Dell, Inc.
 * 
 * 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.dell.doradus.olap.xlink;

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

import com.dell.doradus.common.ApplicationDefinition;
import com.dell.doradus.common.FieldDefinition;
import com.dell.doradus.common.TableDefinition;
import com.dell.doradus.olap.aggregate.mr.MFCollector;
import com.dell.doradus.olap.aggregate.mr.MGName;
import com.dell.doradus.olap.collections.BdLongSet;
import com.dell.doradus.olap.io.BSTR;
import com.dell.doradus.olap.search.Result;
import com.dell.doradus.olap.search.ResultBuilder;
import com.dell.doradus.olap.store.CubeSearcher;
import com.dell.doradus.olap.store.FieldSearcher;
import com.dell.doradus.olap.store.IdSearcher;
import com.dell.doradus.olap.store.IntIterator;
import com.dell.doradus.olap.store.ValueSearcher;
import com.dell.doradus.search.aggregate.AggregationGroup;
import com.dell.doradus.search.aggregate.AggregationGroupItem;
import com.dell.doradus.search.query.AllQuery;
import com.dell.doradus.search.query.Query;

// class representing structures needed during the search/aggregate, if external links are present 
public class XLinkGroupContext {
	
	public XLinkContext context;
	
	public XLinkGroupContext(XLinkContext context) {
		this.context = context;
	}

	public static boolean hasXLink(AggregationGroup group) {
		List items = group.items;
		for(int i = 0; i < items.size(); i++) {
			if(items.get(i).fieldDef.isXLinkField()) return true;
		}
		return false;
	}
	
	public XGroups setupXLinkGroup(AggregationGroup group) {
	    XGroups lastGroup = null;
		if(group.filter != null) context.setupXLinkQuery(group.tableDef, group.filter);
		List items = group.items;
		TableDefinition tableDef = group.tableDef;
		for(int i = items.size() - 1; i >= 0; i--) {
			AggregationGroupItem item = items.get(i);
			if(item.query != null) context.setupXLinkQuery(item.tableDef, item.query);
			if(!item.fieldDef.isXLinkField()) continue;
			group.items = new ArrayList();
			for(int j = i + 1; j < items.size(); j++) {
				group.items.add(items.get(j));
			}
			group.tableDef = item.tableDef;
			XGroups xgroups = setup(item.fieldDef, group, item.query);
			lastGroup = xgroups;
			//XGroups xgroups = new XGroups();
			//if(item.fieldDef.isXLinkDirect()) setupDirect(xgroups, item.fieldDef, group, item.query);
			//else setupInverse(xgroups, item.fieldDef, group, item.query);
			item.xlinkContext = xgroups;
			// restore the group and table def
			group.items = items;
			group.tableDef = tableDef;
		}
		return lastGroup;
	}
	
	private XGroups setup(FieldDefinition fieldDef, AggregationGroup group, Query filter) {
		XGroups xgroups = new XGroups();
		if(fieldDef.getInverseLinkDef().isXLinkDirect()) {
			setupInverse(xgroups, fieldDef, group, filter);
		}
		else {
			setupDirect(xgroups, fieldDef, group, filter);
		}
		return xgroups;
	}
	
	private void setupDirect(XGroups xgroups, FieldDefinition fieldDef, AggregationGroup group, Query filter) {
		if(filter == null) filter = new AllQuery();
		TableDefinition invTable = fieldDef.getInverseTableDef();
		Map names = new HashMap();
		ApplicationDefinition appDef = fieldDef.getTableDef().getAppDef();
		for(String xshard : context.xshards) {
			CubeSearcher searcher = context.olap.getSearcher(appDef, xshard);
			Result bvQuery = ResultBuilder.search(invTable, filter, searcher);
			MFCollector collector = group.items.size() == 0 ?
					new MFCollector.IdField(searcher, invTable) :
					MFCollector.create(searcher, group);
			IdSearcher ids = searcher.getIdSearcher(invTable.getTableName());
			int docsCount = ids.size();
			BdLongSet[] docToFields = new BdLongSet[docsCount];
			BdLongSet allFields = new BdLongSet(1024);
			
			BdLongSet values = new BdLongSet(1024);
			values.enableClearBuffer();
			BdLongSet emptySet = new BdLongSet(1024);
			for(int doc = 0; doc < docsCount; doc++) {
				docToFields[doc] = emptySet;
				if(!bvQuery.get(doc)) continue;
				collector.collect(doc, values);
				if(values.size() > 0) {
					allFields.addAll(values);
					BdLongSet vals = new BdLongSet(values.size());
					vals.addAll(values);
					docToFields[doc] = vals;
					values.clear();
				}
			}
			
			if(collector.requiresOrdering()) allFields.sort();

			Map remap = new HashMap();
			
			for(int i = 0; i < allFields.size(); i++) {
				long num = allFields.get(i);
				MGName fieldName = collector.getField(num);
				Long mappedNum = names.get(fieldName);
				if(mappedNum == null) {
					mappedNum = (long)names.size();
					names.put(fieldName, mappedNum);
					xgroups.groupNames.add(fieldName);
				}
				remap.put(num, mappedNum);
			}
			
			allFields = null;
			
			for(int i = 0; i < docsCount; i++) {
				BSTR id = ids.getId(i);
				BdLongSet orig = docToFields[i];
				docToFields[i] = null;
				if(orig.size() > 0) {
					BdLongSet remapped = new BdLongSet(orig.size());
					for(int j = 0; j < orig.size(); j++) {
						long num = orig.get(j);
						remapped.add(remap.get(num));
					}
					xgroups.groupsMap.put(new BSTR(id), remapped);
				}
			}
		}
	}

	private void setupInverse(XGroups xgroups, FieldDefinition fieldDef, AggregationGroup group, Query filter) {
		if(filter == null) filter = new AllQuery();
		TableDefinition invTable = fieldDef.getInverseTableDef();
		FieldDefinition inv = fieldDef.getInverseLinkDef();
		Map names = new HashMap();
        ApplicationDefinition appDef = fieldDef.getTableDef().getAppDef();
		for(String xshard : context.xshards) {
			CubeSearcher searcher = context.olap.getSearcher(appDef, xshard);
			Result bvQuery = ResultBuilder.search(invTable, filter, searcher);
			
			MFCollector collector = group.items.size() == 0 ?
					new MFCollector.IdField(searcher, invTable) :
					MFCollector.create(searcher, group);
			FieldSearcher fs = searcher.getFieldSearcher(inv.getTableName(), inv.getXLinkJunction());
			IntIterator iter = new IntIterator();
			int docsCount = fs.size();
			BdLongSet[] docToFields = new BdLongSet[fs.fields()];
			BdLongSet allFields = new BdLongSet(1024);
			BdLongSet values = new BdLongSet(1024);
			values.enableClearBuffer();
			for(int doc = 0; doc < docsCount; doc++) {
				if(!bvQuery.get(doc)) continue;
				collector.collect(doc, values);
				allFields.addAll(values);
				fs.fields(doc, iter);
				for(int i = 0; i < iter.count(); i++) {
					int val = iter.get(i);
					BdLongSet vals = docToFields[val];
					if(vals == null) {
						vals = new BdLongSet(values.size());
						docToFields[val] = vals;
					}
					vals.addAll(values);
				}
				values.clear();
			}
			//while(docToFields.size() < fs.fields()) docToFields.add(new HashSet(0));
			
			if(collector.requiresOrdering()) allFields.sort();
			
			Map remap = new HashMap();

			for(int i = 0; i < allFields.size(); i++) {
				long num = allFields.get(i);
				MGName fieldName = collector.getField(num);
				Long mappedNum = names.get(fieldName);
				if(mappedNum == null) {
					mappedNum = (long)names.size();
					names.put(fieldName, mappedNum);
					xgroups.groupNames.add(fieldName);
				}
				remap.put(num, mappedNum);
			}
			
			allFields = null;
			ValueSearcher vs = searcher.getValueSearcher(invTable.getTableName(), inv.getXLinkJunction());
			for(int i = 0; i < vs.size(); i++) {
				BSTR id = vs.getValue(i);
				BdLongSet orig = docToFields[i];
				docToFields[i] = null;;
				if(orig != null && orig.size() > 0) {
					BdLongSet remapped = new BdLongSet(orig.size());
					for(int j = 0; j < orig.size(); j++) {
						long num = orig.get(j);
						remapped.add(remap.get(num));
					}
					BdLongSet currentSet = xgroups.groupsMap.get(id);
					if(currentSet == null) xgroups.groupsMap.put(new BSTR(id), remapped);
					else currentSet.addAll(remapped);
				}
			}
		}
	}
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy