/* This file is part of the db4o object database http://www.db4o.com Copyright (C) 2004 - 2011 Versant Corporation http://www.versant.com db4o is free software; you can redistribute it and/or modify it under the terms of version 3 of the GNU General Public License as published by the Free Software Foundation. db4o 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. */ package com.db4o.internal.query.processor; import com.db4o.*; import com.db4o.foundation.*; import com.db4o.internal.*; public abstract class QCandidateBase extends TreeInt implements InternalCandidate { protected final QCandidates _candidates; protected List4 _dependants; boolean _include = true; Tree _pendingJoins; InternalCandidate _root; public QCandidateBase(QCandidates candidates, int id) { super(id); if (DTrace.enabled) { DTrace.CREATE_CANDIDATE.log(id); } _candidates = candidates; if(id == 0){ _key = candidates.generateCandidateId(); } if(Debug4.queries){ System.out.println("Candidate identified ID:" + _key ); } } protected void addDependant(InternalCandidate a_candidate) { _dependants = new List4(_dependants, a_candidate); } @Override public void doNotInclude() { include(false); if (_dependants != null) { Iterator4 i = new Iterator4Impl(_dependants); _dependants = null; while (i.moveNext()) { ((InternalCandidate) i.current()).doNotInclude(); } } } @Override public boolean evaluate(QPending pending) { if (Debug4.queries) { System.out.println("Pending arrived Join: " + pending._join.id() + " Constraint:" + pending._constraint.id() + " res:" + pending._result); } QPending oldPending = (QPending) Tree.find(_pendingJoins, pending); if (oldPending == null) { pending.changeConstraint(); _pendingJoins = Tree.add(_pendingJoins, pending.internalClonePayload()); return true; } _pendingJoins = _pendingJoins.removeNode(oldPending); oldPending._join.evaluatePending(this, oldPending, pending._result); return false; } public ObjectContainer objectContainer() { return container(); } public InternalCandidate getRoot() { return _root == null ? this : _root; } final LocalObjectContainer container() { return transaction().localContainer(); } @Override public final LocalTransaction transaction() { return _candidates.i_trans; } @Override public boolean include() { return _include; } /** * For external interface use only. Call doNotInclude() internally so * dependancies can be checked. */ public void include(boolean flag) { // TODO: // Internal and external flag may need to be handled seperately. _include = flag; if(Debug4.queries){ System.out.println("Candidate include " + flag + " ID: " + _key); } } @Override public Tree onAttemptToAddDuplicate(Tree oldNode) { _size = 0; _root = (InternalCandidate) oldNode; return oldNode; } @Override public boolean duplicates() { return _root != null; } public QCandidates candidates() { return _candidates; } @Override public void root(InternalCandidate root) { _root = root; } @Override public Tree pendingJoins() { return _pendingJoins; } @Override public int id() { return _key; } }