def produce(self, state): declr_template = self._cgenv.get_template('hash_declaration.cpp') self.right.childtag = "right" self.rightTupleTypeRef = None # may remain None if CSE succeeds my_sch = self.scheme() left_sch = self.left.scheme() right_sch = self.right.scheme() self.leftcols, self.rightcols = \ algebra.convertcondition(self.condition, len(left_sch), left_sch + right_sch) keytype = self.__aggregate_type__(my_sch, self.rightcols) # common index is defined by same right side and same key hashtableInfo = state.lookupExpr((self.right, frozenset(self.rightcols))) if not hashtableInfo: # if right child never bound then store hashtable symbol and # call right child produce self._hashname = self.__genHashName__() _LOG.debug("generate hashname %s for %s", self._hashname, self) hashname = self._hashname # declaration of hash map self.rightTupleTypeRef = state.createUnresolvedSymbol() in_tuple_type = self.rightTupleTypeRef.getPlaceholder() hashdeclr = declr_template.render(locals()) state.addDeclarationsUnresolved([hashdeclr]) init_template = self._cgenv.get_template('hash_init.cpp') state.addInitializers([init_template.render(locals())]) self.right.produce(state) state.saveExpr((self.right, frozenset(self.rightcols)), (self._hashname, self.rightTupleTypename, self.right_syncname)) # TODO always safe here? I really want to call # TODO saveExpr before self.right.produce(), # TODO but I need to get the self.rightTupleTypename cleanly else: # if found a common subexpression on right child then # use the same hashtable self._hashname, self.rightTupleTypename, self.right_syncname\ = hashtableInfo _LOG.debug("reuse hash %s for %s", self._hashname, self) self.left.childtag = "left" self.left.produce(state)
def produce(self, state): self.symBase = self.__genBaseName__() init_template = self._cgenv.get_template('hash_init.cpp') declr_template = self._cgenv.get_template('hash_declaration.cpp') my_sch = self.scheme() left_sch = self.left.scheme() right_sch = self.right.scheme() self.leftcols, self.rightcols = \ algebra.convertcondition(self.condition, len(left_sch), left_sch + right_sch) # declaration of hash map self._hashname = self.__getHashName__() keytype = self.__aggregate_type__(my_sch, self.rightcols) hashname = self._hashname self.leftTypeRef = state.createUnresolvedSymbol() left_in_tuple_type = self.leftTypeRef.getPlaceholder() self.rightTypeRef = state.createUnresolvedSymbol() right_in_tuple_type = self.rightTypeRef.getPlaceholder() hashdeclr = declr_template.render(locals()) state.addDeclarationsUnresolved([hashdeclr]) self.outTuple = GrappaStagedTupleRef(gensym(), my_sch) out_tuple_type_def = self.outTuple.generateDefinition() state.addDeclarations([out_tuple_type_def]) self.right.childtag = "right" state.addInitializers([init_template.render(locals())]) self.right.produce(state) self.left.childtag = "left" self.left.produce(state)