示例#1
0
int main(void){
	struct hashtable *ht;
	char *buffer;
	struct mypasswd* pw, *last_found;
	int i;

	ht = build_hash_table("/etc/group", 4, 3, 1, 100, 0, ":");
	if(!ht) {
		printf("Hash table not built\n");
		return -1;
	}
	for (i = 0; i < ht->tablesize; i++) {
		if (ht->table[i]) {
			printf("%d:\n", i);
			for (pw = ht->table[i]; pw; pw = pw->next) {
				printpw(pw, 4);
			}
		}
	}

	while(fgets(buffer, 1024, stdin)){
		buffer[strlen(buffer)-1] = 0;
		pw = get_pw_nam(buffer, ht, &last_found);
		printpw(pw,4);
		while ((pw = get_next(buffer, ht, &last_found))) printpw(pw,4);
	}
	release_ht(ht);
}
/* ----------------------------------------------------------------
 *		ExecReScanRecursiveUnion
 *
 *		Rescans the relation.
 * ----------------------------------------------------------------
 */
void
ExecReScanRecursiveUnion(RecursiveUnionState *node)
{
	PlanState  *outerPlan = outerPlanState(node);
	PlanState  *innerPlan = innerPlanState(node);
	RecursiveUnion *plan = (RecursiveUnion *) node->ps.plan;

	/*
	 * Set recursive term's chgParam to tell it that we'll modify the working
	 * table and therefore it has to rescan.
	 */
	innerPlan->chgParam = bms_add_member(innerPlan->chgParam, plan->wtParam);

	/*
	 * if chgParam of subnode is not null then plan will be re-scanned by
	 * first ExecProcNode.	Because of above, we only have to do this to the
	 * non-recursive term.
	 */
	if (outerPlan->chgParam == NULL)
		ExecReScan(outerPlan);

	/* Release any hashtable storage */
	if (node->tableContext)
		MemoryContextResetAndDeleteChildren(node->tableContext);

	/* And rebuild empty hashtable if needed */
	if (plan->numCols > 0)
		build_hash_table(node);

	/* reset processing state */
	node->recursing = false;
	node->intermediate_empty = true;
	tuplestore_clear(node->working_table);
	tuplestore_clear(node->intermediate_table);
}
示例#3
0
void
ExecReScanSetOp(SetOpState *node)
{
	ExecClearTuple(node->ps.ps_ResultTupleSlot);
	node->setop_done = false;
	node->numOutput = 0;

	if (((SetOp *) node->ps.plan)->strategy == SETOP_HASHED)
	{
		/*
		 * In the hashed case, if we haven't yet built the hash table then we
		 * can just return; nothing done yet, so nothing to undo. If subnode's
		 * chgParam is not NULL then it will be re-scanned by ExecProcNode,
		 * else no reason to re-scan it at all.
		 */
		if (!node->table_filled)
			return;

		/*
		 * If we do have the hash table and the subplan does not have any
		 * parameter changes, then we can just rescan the existing hash table;
		 * no need to build it again.
		 */
		if (node->ps.lefttree->chgParam == NULL)
		{
			ResetTupleHashIterator(node->hashtable, &node->hashiter);
			return;
		}
	}

	/* Release first tuple of group, if we have made a copy */
	if (node->grp_firstTuple != NULL)
	{
		heap_freetuple(node->grp_firstTuple);
		node->grp_firstTuple = NULL;
	}

	/* Release any hashtable storage */
	if (node->tableContext)
		MemoryContextResetAndDeleteChildren(node->tableContext);

	/* And rebuild empty hashtable if needed */
	if (((SetOp *) node->ps.plan)->strategy == SETOP_HASHED)
	{
		build_hash_table(node);
		node->table_filled = false;
	}

	/*
	 * if chgParam of subnode is not null then plan will be re-scanned by
	 * first ExecProcNode.
	 */
	if (node->ps.lefttree->chgParam == NULL)
		ExecReScan(node->ps.lefttree);
}
示例#4
0
int main( int argc, char **argv )
{
    if(argc < 3) {
        CL_INFO_PRINT("at least two argument!\n");
    }
    /* ************
    filename1  wait sync
    filename2  dest
    **************/
    char *filename1,*filename2;
    int fd1,fd2;
    char * buf;
    uint32 checksum1;
    struct stat st;
    struct chunk_descriptor *chunk_desc;
    struct chunk_modify_descriptor chunk_modify_desc;
    filename1 = argv[1];
    filename2 = argv[2];
    chunk_desc = malloc(sizeof(struct chunk_descriptor));
    if(!chunk_desc) {
        CL_ERR_PRINT("out memory");
        return -1;
    }
    if(get_file_stat(filename1,chunk_desc)!=0) {
        return -1;
    }
    build_hash_table(chunk_desc);
    init_chunk_modify_descriptor(&chunk_modify_desc);
    generate_modify_descriptor(filename2,&chunk_modify_desc,chunk_desc);
    // print_hash_stat();
     // print_chunk_modify(&chunk_modify_desc);
    sync_file(filename1,&chunk_modify_desc);
    cleanup_modify_list(&chunk_modify_desc);
    cleanup_hash_list();

    free(chunk_desc->chunk);
    free(chunk_desc);
    return 0;
}
示例#5
0
/* ----------------------------------------------------------------
 *		ExecInitSetOp
 *
 *		This initializes the setop node state structures and
 *		the node's subplan.
 * ----------------------------------------------------------------
 */
SetOpState *
ExecInitSetOp(SetOp *node, EState *estate, int eflags)
{
	SetOpState *setopstate;

	/* check for unsupported flags */
	Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));

	/*
	 * create state structure
	 */
	setopstate = makeNode(SetOpState);
	setopstate->ps.plan = (Plan *) node;
	setopstate->ps.state = estate;

	setopstate->eqfunctions = NULL;
	setopstate->hashfunctions = NULL;
	setopstate->setop_done = false;
	setopstate->numOutput = 0;
	setopstate->pergroup = NULL;
	setopstate->grp_firstTuple = NULL;
	setopstate->hashtable = NULL;
	setopstate->tableContext = NULL;

	/*
	 * Miscellaneous initialization
	 *
	 * SetOp nodes have no ExprContext initialization because they never call
	 * ExecQual or ExecProject.  But they do need a per-tuple memory context
	 * anyway for calling execTuplesMatch.
	 */
	setopstate->tempContext =
		AllocSetContextCreate(CurrentMemoryContext,
							  "SetOp",
							  ALLOCSET_DEFAULT_MINSIZE,
							  ALLOCSET_DEFAULT_INITSIZE,
							  ALLOCSET_DEFAULT_MAXSIZE);

	/*
	 * If hashing, we also need a longer-lived context to store the hash
	 * table.  The table can't just be kept in the per-query context because
	 * we want to be able to throw it away in ExecReScanSetOp.
	 */
	if (node->strategy == SETOP_HASHED)
		setopstate->tableContext =
			AllocSetContextCreate(CurrentMemoryContext,
								  "SetOp hash table",
								  ALLOCSET_DEFAULT_MINSIZE,
								  ALLOCSET_DEFAULT_INITSIZE,
								  ALLOCSET_DEFAULT_MAXSIZE);

	/*
	 * Tuple table initialization
	 */
	ExecInitResultTupleSlot(estate, &setopstate->ps);

	/*
	 * initialize child nodes
	 *
	 * If we are hashing then the child plan does not need to handle REWIND
	 * efficiently; see ExecReScanSetOp.
	 */
	if (node->strategy == SETOP_HASHED)
		eflags &= ~EXEC_FLAG_REWIND;
	outerPlanState(setopstate) = ExecInitNode(outerPlan(node), estate, eflags);

	/*
	 * setop nodes do no projections, so initialize projection info for this
	 * node appropriately
	 */
	ExecAssignResultTypeFromTL(&setopstate->ps);
	setopstate->ps.ps_ProjInfo = NULL;

	/*
	 * Precompute fmgr lookup data for inner loop. We need both equality and
	 * hashing functions to do it by hashing, but only equality if not
	 * hashing.
	 */
	if (node->strategy == SETOP_HASHED)
		execTuplesHashPrepare(node->numCols,
							  node->dupOperators,
							  &setopstate->eqfunctions,
							  &setopstate->hashfunctions);
	else
		setopstate->eqfunctions =
			execTuplesMatchPrepare(node->numCols,
								   node->dupOperators);

	if (node->strategy == SETOP_HASHED)
	{
		build_hash_table(setopstate);
		setopstate->table_filled = false;
	}
	else
	{
		setopstate->pergroup =
			(SetOpStatePerGroup) palloc0(sizeof(SetOpStatePerGroupData));
	}

	return setopstate;
}
示例#6
0
/**
 * Scan through a origin file, looking for sections that match
 * checksums from the generator, and transmit either literal or token
 * data.
 *
 * Also calculates the MD4 checksum of the whole file, using the md
 * accumulator.  This is transmitted with the file as protection
 * against corruption on the wire.
 *
 * @param s Checksums received from the generator.  If <tt>s->count ==
 * 0</tt>, then there are actually no checksums for this file.
 *
 * @param len Length of the file to send.
 **/
void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
{
	int sum_len;

	last_match = 0;
	false_alarms = 0;
	hash_hits = 0;
	matches = 0;
	data_transfer = 0;

	sum_init(xfersum_type, checksum_seed);

	if (append_mode > 0) {
		if (append_mode == 2) {
			OFF_T j = 0;
			for (j = CHUNK_SIZE; j < s->flength; j += CHUNK_SIZE) {
				if (buf && INFO_GTE(PROGRESS, 1))
					show_progress(last_match, buf->file_size);
				sum_update(map_ptr(buf, last_match, CHUNK_SIZE),
					   CHUNK_SIZE);
				last_match = j;
			}
			if (last_match < s->flength) {
				int32 n = (int32)(s->flength - last_match);
				if (buf && INFO_GTE(PROGRESS, 1))
					show_progress(last_match, buf->file_size);
				sum_update(map_ptr(buf, last_match, n), n);
			}
		}
		last_match = s->flength;
		s->count = 0;
	}

	if (len > 0 && s->count > 0) {
		build_hash_table(s);

		if (DEBUG_GTE(DELTASUM, 2))
			rprintf(FINFO,"built hash table\n");

		hash_search(f, s, buf, len);

		if (DEBUG_GTE(DELTASUM, 2))
			rprintf(FINFO,"done hash search\n");
	} else {
		OFF_T j;
		/* by doing this in pieces we avoid too many seeks */
		for (j = last_match + CHUNK_SIZE; j < len; j += CHUNK_SIZE)
			matched(f, s, buf, j, -2);
		matched(f, s, buf, len, -1);
	}

	sum_len = sum_end(sender_file_sum);

	/* If we had a read error, send a bad checksum.  We use all bits
	 * off as long as the checksum doesn't happen to be that, in
	 * which case we turn the last 0 bit into a 1. */
	if (buf && buf->status != 0) {
		int i;
		for (i = 0; i < sum_len && sender_file_sum[i] == 0; i++) {}
		memset(sender_file_sum, 0, sum_len);
		if (i == sum_len)
			sender_file_sum[i-1]++;
	}

	if (DEBUG_GTE(DELTASUM, 2))
		rprintf(FINFO,"sending file_sum\n");
	write_buf(f, sender_file_sum, sum_len);

	if (DEBUG_GTE(DELTASUM, 2)) {
		rprintf(FINFO, "false_alarms=%d hash_hits=%d matches=%d\n",
			false_alarms, hash_hits, matches);
	}

	total_hash_hits += hash_hits;
	total_false_alarms += false_alarms;
	total_matches += matches;
	stats.literal_data += data_transfer;
}
示例#7
0
/**
 * Scan through a origin file, looking for sections that match
 * checksums from the generator, and transmit either literal or token
 * data.
 *
 * Also calculates the MD4 checksum of the whole file, using the md
 * accumulator.  This is transmitted with the file as protection
 * against corruption on the wire.
 *
 * @param s Checksums received from the generator.  If <tt>s->count ==
 * 0</tt>, then there are actually no checksums for this file.
 *
 * @param len Length of the file to send.
 **/
void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
{
	char file_sum[MD4_SUM_LENGTH];

	last_match = 0;
	false_alarms = 0;
	hash_hits = 0;
	matches = 0;
	data_transfer = 0;

	sum_init(checksum_seed);

	if (append_mode > 0) {
		OFF_T j = 0;
		for (j = CHUNK_SIZE; j < s->flength; j += CHUNK_SIZE) {
			if (buf && do_progress)
				show_progress(last_match, buf->file_size);
			sum_update(map_ptr(buf, last_match, CHUNK_SIZE),
				   CHUNK_SIZE);
			last_match = j;
		}
		if (last_match < s->flength) {
			int32 len = (int32)(s->flength - last_match);
			if (buf && do_progress)
				show_progress(last_match, buf->file_size);
			sum_update(map_ptr(buf, last_match, len), len);
			last_match = s->flength;
		}
		s->count = 0;
	}

	if (len > 0 && s->count > 0) {
		build_hash_table(s);

		if (verbose > 2)
			rprintf(FINFO,"built hash table\n");

		hash_search(f,s,buf,len);

		if (verbose > 2)
			rprintf(FINFO,"done hash search\n");
	} else {
		OFF_T j;
		/* by doing this in pieces we avoid too many seeks */
		for (j = last_match + CHUNK_SIZE; j < len; j += CHUNK_SIZE)
			matched(f, s, buf, j, -2);
		matched(f, s, buf, len, -1);
	}

	sum_end(file_sum);
	/* If we had a read error, send a bad checksum. */
	if (buf && buf->status != 0)
		file_sum[0]++;

	if (verbose > 2)
		rprintf(FINFO,"sending file_sum\n");
	write_buf(f,file_sum,MD4_SUM_LENGTH);

	if (verbose > 2)
		rprintf(FINFO, "false_alarms=%d hash_hits=%d matches=%d\n",
			false_alarms, hash_hits, matches);

	total_hash_hits += hash_hits;
	total_false_alarms += false_alarms;
	total_matches += matches;
	stats.literal_data += data_transfer;
}
示例#8
0
int
print_insn_sparc (bfd_vma memaddr, disassemble_info *info)
{
  FILE *stream = info->stream;
  bfd_byte buffer[4];
  unsigned long insn;
  sparc_opcode_hash *op;
  /* Nonzero of opcode table has been initialized.  */
  static int opcodes_initialized = 0;
  /* bfd mach number of last call.  */
  static unsigned long current_mach = 0;
  bfd_vma (*getword) (const void *);

  if (!opcodes_initialized
      || info->mach != current_mach)
    {
      int i;

      current_arch_mask = compute_arch_mask (info->mach);

      if (!opcodes_initialized)
	sorted_opcodes =
	  xmalloc (sparc_num_opcodes * sizeof (sparc_opcode *));
      /* Reset the sorted table so we can resort it.  */
      for (i = 0; i < sparc_num_opcodes; ++i)
	sorted_opcodes[i] = &sparc_opcodes[i];
      qsort ((char *) sorted_opcodes, sparc_num_opcodes,
	     sizeof (sorted_opcodes[0]), compare_opcodes);

      build_hash_table (sorted_opcodes, opcode_hash_table, sparc_num_opcodes);
      current_mach = info->mach;
      opcodes_initialized = 1;
    }

  {
    int status =
      (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);

    if (status != 0)
      {
	(*info->memory_error_func) (status, memaddr, info);
	return -1;
      }
  }

  /* On SPARClite variants such as DANlite (sparc86x), instructions
     are always big-endian even when the machine is in little-endian mode.  */
  if (info->endian == BFD_ENDIAN_BIG || info->mach == bfd_mach_sparc_sparclite)
    getword = bfd_getb32;
  else
    getword = bfd_getl32;

  insn = getword (buffer);

  info->insn_info_valid = 1;			/* We do return this info.  */
  info->insn_type = dis_nonbranch;		/* Assume non branch insn.  */
  info->branch_delay_insns = 0;			/* Assume no delay.  */
  info->target = 0;				/* Assume no target known.  */

  for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
    {
      const sparc_opcode *opcode = op->opcode;

      /* If the insn isn't supported by the current architecture, skip it.  */
      if (! (opcode->architecture & current_arch_mask))
	continue;

      if ((opcode->match & insn) == opcode->match
	  && (opcode->lose & insn) == 0)
	{
	  /* Nonzero means that we have found an instruction which has
	     the effect of adding or or'ing the imm13 field to rs1.  */
	  int imm_added_to_rs1 = 0;
	  int imm_ored_to_rs1 = 0;

	  /* Nonzero means that we have found a plus sign in the args
	     field of the opcode table.  */
	  int found_plus = 0;

	  /* Nonzero means we have an annulled branch.  */
	  int is_annulled = 0;

	  /* Do we have an `add' or `or' instruction combining an
             immediate with rs1?  */
	  if (opcode->match == 0x80102000) /* or */
	    imm_ored_to_rs1 = 1;
	  if (opcode->match == 0x80002000) /* add */
	    imm_added_to_rs1 = 1;

	  if (X_RS1 (insn) != X_RD (insn)
	      && strchr (opcode->args, 'r') != 0)
	      /* Can't do simple format if source and dest are different.  */
	      continue;
	  if (X_RS2 (insn) != X_RD (insn)
	      && strchr (opcode->args, 'O') != 0)
	      /* Can't do simple format if source and dest are different.  */
	      continue;

	  (*info->fprintf_func) (stream, "%s", opcode->name);

	  {
	    const char *s;

	    if (opcode->args[0] != ',')
	      (*info->fprintf_func) (stream, " ");

	    for (s = opcode->args; *s != '\0'; ++s)
	      {
		while (*s == ',')
		  {
		    (*info->fprintf_func) (stream, ",");
		    ++s;
		    switch (*s)
		      {
		      case 'a':
			(*info->fprintf_func) (stream, "a");
			is_annulled = 1;
			++s;
			continue;
		      case 'N':
			(*info->fprintf_func) (stream, "pn");
			++s;
			continue;

		      case 'T':
			(*info->fprintf_func) (stream, "pt");
			++s;
			continue;

		      default:
			break;
		      }
		  }

		(*info->fprintf_func) (stream, " ");

		switch (*s)
		  {
		  case '+':
		    found_plus = 1;
		    /* Fall through.  */

		  default:
		    (*info->fprintf_func) (stream, "%c", *s);
		    break;

		  case '#':
		    (*info->fprintf_func) (stream, "0");
		    break;

#define	reg(n)	(*info->fprintf_func) (stream, "%%%s", reg_names[n])
		  case '1':
		  case 'r':
		    reg (X_RS1 (insn));
		    break;

		  case '2':
		  case 'O':
		    reg (X_RS2 (insn));
		    break;

		  case 'd':
		    reg (X_RD (insn));
		    break;
#undef	reg

#define	freg(n)		(*info->fprintf_func) (stream, "%%%s", freg_names[n])
#define	fregx(n)	(*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)])
		  case 'e':
		    freg (X_RS1 (insn));
		    break;
		  case 'v':	/* Double/even.  */
		  case 'V':	/* Quad/multiple of 4.  */
		    fregx (X_RS1 (insn));
		    break;

		  case 'f':
		    freg (X_RS2 (insn));
		    break;
		  case 'B':	/* Double/even.  */
		  case 'R':	/* Quad/multiple of 4.  */
		    fregx (X_RS2 (insn));
		    break;

		  case '4':
		    freg (X_RS3 (insn));
		    break;
		  case '5':	/* Double/even.  */
		    fregx (X_RS3 (insn));
		    break;

		  case 'g':
		    freg (X_RD (insn));
		    break;
		  case 'H':	/* Double/even.  */
		  case 'J':	/* Quad/multiple of 4.  */
		  case '}':     /* Double/even.  */
		    fregx (X_RD (insn));
		    break;
#undef	freg
#undef	fregx

#define	creg(n)	(*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n))
		  case 'b':
		    creg (X_RS1 (insn));
		    break;

		  case 'c':
		    creg (X_RS2 (insn));
		    break;

		  case 'D':
		    creg (X_RD (insn));
		    break;
#undef	creg

		  case 'h':
		    (*info->fprintf_func) (stream, "%%hi(%#x)",
					   ((unsigned) 0xFFFFFFFF
					    & ((int) X_IMM22 (insn) << 10)));
		    break;

		  case 'i':	/* 13 bit immediate.  */
		  case 'I':	/* 11 bit immediate.  */
		  case 'j':	/* 10 bit immediate.  */
		    {
		      int imm;

		      if (*s == 'i')
		        imm = X_SIMM (insn, 13);
		      else if (*s == 'I')
			imm = X_SIMM (insn, 11);
		      else
			imm = X_SIMM (insn, 10);

		      /* Check to see whether we have a 1+i, and take
			 note of that fact.

			 Note: because of the way we sort the table,
			 we will be matching 1+i rather than i+1,
			 so it is OK to assume that i is after +,
			 not before it.  */
		      if (found_plus)
			imm_added_to_rs1 = 1;

		      if (imm <= 9)
			(*info->fprintf_func) (stream, "%d", imm);
		      else
			(*info->fprintf_func) (stream, "%#x", imm);
		    }
		    break;

		  case ')':	/* 5 bit unsigned immediate from RS3.  */
		    (info->fprintf_func) (stream, "%#x", (unsigned int) X_RS3 (insn));
		    break;

		  case 'X':	/* 5 bit unsigned immediate.  */
		  case 'Y':	/* 6 bit unsigned immediate.  */
		    {
		      int imm = X_IMM (insn, *s == 'X' ? 5 : 6);

		      if (imm <= 9)
			(info->fprintf_func) (stream, "%d", imm);
		      else
			(info->fprintf_func) (stream, "%#x", (unsigned) imm);
		    }
		    break;

		  case '3':
		    (info->fprintf_func) (stream, "%ld", X_IMM (insn, 3));
		    break;

		  case 'K':
		    {
		      int mask = X_MEMBAR (insn);
		      int bit = 0x40, printed_one = 0;
		      const char *name;

		      if (mask == 0)
			(info->fprintf_func) (stream, "0");
		      else
			while (bit)
			  {
			    if (mask & bit)
			      {
				if (printed_one)
				  (info->fprintf_func) (stream, "|");
				name = sparc_decode_membar (bit);
				(info->fprintf_func) (stream, "%s", name);
				printed_one = 1;
			      }
			    bit >>= 1;
			  }
		      break;
		    }

		  case '=':
		    info->target = memaddr + SEX (X_DISP10 (insn), 10) * 4;
		    (*info->print_address_func) (info->target, info);
		    break;

		  case 'k':
		    info->target = memaddr + SEX (X_DISP16 (insn), 16) * 4;
		    (*info->print_address_func) (info->target, info);
		    break;

		  case 'G':
		    info->target = memaddr + SEX (X_DISP19 (insn), 19) * 4;
		    (*info->print_address_func) (info->target, info);
		    break;

		  case '6':
		  case '7':
		  case '8':
		  case '9':
		    (*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0');
		    break;

		  case 'z':
		    (*info->fprintf_func) (stream, "%%icc");
		    break;

		  case 'Z':
		    (*info->fprintf_func) (stream, "%%xcc");
		    break;

		  case 'E':
		    (*info->fprintf_func) (stream, "%%ccr");
		    break;

		  case 's':
		    (*info->fprintf_func) (stream, "%%fprs");
		    break;

		  case '{':
		    (*info->fprintf_func) (stream, "%%mcdper");
		    break;

		  case 'o':
		    (*info->fprintf_func) (stream, "%%asi");
		    break;

		  case 'W':
		    (*info->fprintf_func) (stream, "%%tick");
		    break;

		  case 'P':
		    (*info->fprintf_func) (stream, "%%pc");
		    break;

		  case '?':
		    if (X_RS1 (insn) == 31)
		      (*info->fprintf_func) (stream, "%%ver");
		    else if (X_RS1 (insn) == 23)
		      (*info->fprintf_func) (stream, "%%pmcdper");
		    else if ((unsigned) X_RS1 (insn) < 17)
		      (*info->fprintf_func) (stream, "%%%s",
					     v9_priv_reg_names[X_RS1 (insn)]);
		    else
		      (*info->fprintf_func) (stream, "%%reserved");
		    break;

		  case '!':
                    if (X_RD (insn) == 31)
                      (*info->fprintf_func) (stream, "%%ver");
		    else if (X_RD (insn) == 23)
		      (*info->fprintf_func) (stream, "%%pmcdper");
		    else if ((unsigned) X_RD (insn) < 17)
		      (*info->fprintf_func) (stream, "%%%s",
					     v9_priv_reg_names[X_RD (insn)]);
		    else
		      (*info->fprintf_func) (stream, "%%reserved");
		    break;

		  case '$':
		    if ((unsigned) X_RS1 (insn) < 32)
		      (*info->fprintf_func) (stream, "%%%s",
					     v9_hpriv_reg_names[X_RS1 (insn)]);
		    else
		      (*info->fprintf_func) (stream, "%%reserved");
		    break;

		  case '%':
		    if ((unsigned) X_RD (insn) < 32)
		      (*info->fprintf_func) (stream, "%%%s",
					     v9_hpriv_reg_names[X_RD (insn)]);
		    else
		      (*info->fprintf_func) (stream, "%%reserved");
		    break;

		  case '/':
		    if (X_RS1 (insn) < 16 || X_RS1 (insn) > 28)
		      (*info->fprintf_func) (stream, "%%reserved");
		    else
		      (*info->fprintf_func) (stream, "%%%s",
					     v9a_asr_reg_names[X_RS1 (insn)-16]);
		    break;

		  case '_':
		    if (X_RD (insn) < 16 || X_RD (insn) > 28)
		      (*info->fprintf_func) (stream, "%%reserved");
		    else
		      (*info->fprintf_func) (stream, "%%%s",
					     v9a_asr_reg_names[X_RD (insn)-16]);
		    break;

		  case '*':
		    {
		      const char *name = sparc_decode_prefetch (X_RD (insn));

		      if (name)
			(*info->fprintf_func) (stream, "%s", name);
		      else
			(*info->fprintf_func) (stream, "%ld", X_RD (insn));
		      break;
		    }

		  case 'M':
		    (*info->fprintf_func) (stream, "%%asr%ld", X_RS1 (insn));
		    break;

		  case 'm':
		    (*info->fprintf_func) (stream, "%%asr%ld", X_RD (insn));
		    break;

		  case 'L':
		    info->target = memaddr + SEX (X_DISP30 (insn), 30) * 4;
		    (*info->print_address_func) (info->target, info);
		    break;

		  case 'n':
		    (*info->fprintf_func)
		      (stream, "%#x", SEX (X_DISP22 (insn), 22));
		    break;

		  case 'l':
		    info->target = memaddr + SEX (X_DISP22 (insn), 22) * 4;
		    (*info->print_address_func) (info->target, info);
		    break;

		  case 'A':
		    {
		      const char *name = sparc_decode_asi (X_ASI (insn));

		      if (name)
			(*info->fprintf_func) (stream, "%s", name);
		      else
			(*info->fprintf_func) (stream, "(%ld)", X_ASI (insn));
		      break;
		    }

		  case 'C':
		    (*info->fprintf_func) (stream, "%%csr");
		    break;

		  case 'F':
		    (*info->fprintf_func) (stream, "%%fsr");
		    break;

		  case '(':
		    (*info->fprintf_func) (stream, "%%efsr");
		    break;

		  case 'p':
		    (*info->fprintf_func) (stream, "%%psr");
		    break;

		  case 'q':
		    (*info->fprintf_func) (stream, "%%fq");
		    break;

		  case 'Q':
		    (*info->fprintf_func) (stream, "%%cq");
		    break;

		  case 't':
		    (*info->fprintf_func) (stream, "%%tbr");
		    break;

		  case 'w':
		    (*info->fprintf_func) (stream, "%%wim");
		    break;

		  case 'x':
		    (*info->fprintf_func) (stream, "%ld",
					   ((X_LDST_I (insn) << 8)
					    + X_ASI (insn)));
		    break;

		  case 'y':
		    (*info->fprintf_func) (stream, "%%y");
		    break;

		  case 'u':
		  case 'U':
		    {
		      int val = *s == 'U' ? X_RS1 (insn) : X_RD (insn);
		      const char *name = sparc_decode_sparclet_cpreg (val);

		      if (name)
			(*info->fprintf_func) (stream, "%s", name);
		      else
			(*info->fprintf_func) (stream, "%%cpreg(%d)", val);
		      break;
		    }
		  }
	      }
	  }

	  /* If we are adding or or'ing something to rs1, then
	     check to see whether the previous instruction was
	     a sethi to the same register as in the sethi.
	     If so, attempt to print the result of the add or
	     or (in this context add and or do the same thing)
	     and its symbolic value.  */
	  if (imm_ored_to_rs1 || imm_added_to_rs1)
	    {
	      unsigned long prev_insn;
	      int errcode;

	      if (memaddr >= 4)
		errcode =
		  (*info->read_memory_func)
		  (memaddr - 4, buffer, sizeof (buffer), info);
	      else
		errcode = 1;

	      prev_insn = getword (buffer);

	      if (errcode == 0)
		{
		  /* If it is a delayed branch, we need to look at the
		     instruction before the delayed branch.  This handles
		     sequences such as:

		     sethi %o1, %hi(_foo), %o1
		     call _printf
		     or %o1, %lo(_foo), %o1  */

		  if (is_delayed_branch (prev_insn))
		    {
		      if (memaddr >= 8)
			errcode = (*info->read_memory_func)
			  (memaddr - 8, buffer, sizeof (buffer), info);
		      else
			errcode = 1;

		      prev_insn = getword (buffer);
		    }
		}

	      /* If there was a problem reading memory, then assume
		 the previous instruction was not sethi.  */
	      if (errcode == 0)
		{
		  /* Is it sethi to the same register?  */
		  if ((prev_insn & 0xc1c00000) == 0x01000000
		      && X_RD (prev_insn) == X_RS1 (insn))
		    {
		      (*info->fprintf_func) (stream, "\t! ");
		      info->target =
			((unsigned) 0xFFFFFFFF
			 & ((int) X_IMM22 (prev_insn) << 10));
		      if (imm_added_to_rs1)
			info->target += X_SIMM (insn, 13);
		      else
			info->target |= X_SIMM (insn, 13);
		      (*info->print_address_func) (info->target, info);
		      info->insn_type = dis_dref;
		      info->data_size = 4;  /* FIXME!!! */
		    }
		}
	    }

	  if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR))
	    {
	      /* FIXME -- check is_annulled flag.  */
	      (void) is_annulled;
	      if (opcode->flags & F_UNBR)
		info->insn_type = dis_branch;
	      if (opcode->flags & F_CONDBR)
		info->insn_type = dis_condbranch;
	      if (opcode->flags & F_JSR)
		info->insn_type = dis_jsr;
	      if (opcode->flags & F_DELAYED)
		info->branch_delay_insns = 1;
	    }

	  return sizeof (buffer);
	}
    }
/* ----------------------------------------------------------------
 *		ExecInitRecursiveUnionScan
 * ----------------------------------------------------------------
 */
RecursiveUnionState *
ExecInitRecursiveUnion(RecursiveUnion *node, EState *estate, int eflags)
{
	RecursiveUnionState *rustate;
	ParamExecData *prmdata;

	/* check for unsupported flags */
	Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));

	/*
	 * create state structure
	 */
	rustate = makeNode(RecursiveUnionState);
	rustate->ps.plan = (Plan *) node;
	rustate->ps.state = estate;

	rustate->eqfunctions = NULL;
	rustate->hashfunctions = NULL;
	rustate->hashtable = NULL;
	rustate->tempContext = NULL;
	rustate->tableContext = NULL;

	/* initialize processing state */
	rustate->recursing = false;
	rustate->intermediate_empty = true;
	rustate->working_table = tuplestore_begin_heap(false, false, work_mem);
	rustate->intermediate_table = tuplestore_begin_heap(false, false, work_mem);

	/*
	 * If hashing, we need a per-tuple memory context for comparisons, and a
	 * longer-lived context to store the hash table.  The table can't just be
	 * kept in the per-query context because we want to be able to throw it
	 * away when rescanning.
	 */
	if (node->numCols > 0)
	{
		rustate->tempContext =
			AllocSetContextCreate(CurrentMemoryContext,
								  "RecursiveUnion",
								  ALLOCSET_DEFAULT_MINSIZE,
								  ALLOCSET_DEFAULT_INITSIZE,
								  ALLOCSET_DEFAULT_MAXSIZE);
		rustate->tableContext =
			AllocSetContextCreate(CurrentMemoryContext,
								  "RecursiveUnion hash table",
								  ALLOCSET_DEFAULT_MINSIZE,
								  ALLOCSET_DEFAULT_INITSIZE,
								  ALLOCSET_DEFAULT_MAXSIZE);
	}

	/*
	 * Make the state structure available to descendant WorkTableScan nodes
	 * via the Param slot reserved for it.
	 */
	prmdata = &(estate->es_param_exec_vals[node->wtParam]);
	Assert(prmdata->execPlan == NULL);
	prmdata->value = PointerGetDatum(rustate);
	prmdata->isnull = false;

	/*
	 * Miscellaneous initialization
	 *
	 * RecursiveUnion plans don't have expression contexts because they never
	 * call ExecQual or ExecProject.
	 */
	Assert(node->plan.qual == NIL);

	/*
	 * RecursiveUnion nodes still have Result slots, which hold pointers to
	 * tuples, so we have to initialize them.
	 */
	ExecInitResultTupleSlot(estate, &rustate->ps);

	/*
	 * Initialize result tuple type and projection info.  (Note: we have to
	 * set up the result type before initializing child nodes, because
	 * nodeWorktablescan.c expects it to be valid.)
	 */
	ExecAssignResultTypeFromTL(&rustate->ps);
	rustate->ps.ps_ProjInfo = NULL;

	/*
	 * initialize child nodes
	 */
	outerPlanState(rustate) = ExecInitNode(outerPlan(node), estate, eflags);
	innerPlanState(rustate) = ExecInitNode(innerPlan(node), estate, eflags);

	/*
	 * If hashing, precompute fmgr lookup data for inner loop, and create the
	 * hash table.
	 */
	if (node->numCols > 0)
	{
		execTuplesHashPrepare(node->numCols,
							  node->dupOperators,
							  &rustate->eqfunctions,
							  &rustate->hashfunctions);
		build_hash_table(rustate);
	}

	return rustate;
}
示例#10
0
/* ----------------------------------------------------------------
 *		ExecInitSetOp
 *
 *		This initializes the setop node state structures and
 *		the node's subplan.
 * ----------------------------------------------------------------
 */
SetOpState *
ExecInitSetOp(SetOp *node, EState *estate, int eflags)
{
	SetOpState *setopstate;
	TupleDesc	outerDesc;

	/* check for unsupported flags */
	Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));

	/*
	 * create state structure
	 */
	setopstate = makeNode(SetOpState);
	setopstate->ps.plan = (Plan *) node;
	setopstate->ps.state = estate;
	setopstate->ps.ExecProcNode = ExecSetOp;

	setopstate->eqfuncoids = NULL;
	setopstate->hashfunctions = NULL;
	setopstate->setop_done = false;
	setopstate->numOutput = 0;
	setopstate->pergroup = NULL;
	setopstate->grp_firstTuple = NULL;
	setopstate->hashtable = NULL;
	setopstate->tableContext = NULL;

	/*
	 * create expression context
	 */
	ExecAssignExprContext(estate, &setopstate->ps);

	/*
	 * If hashing, we also need a longer-lived context to store the hash
	 * table.  The table can't just be kept in the per-query context because
	 * we want to be able to throw it away in ExecReScanSetOp.
	 */
	if (node->strategy == SETOP_HASHED)
		setopstate->tableContext =
			AllocSetContextCreate(CurrentMemoryContext,
								  "SetOp hash table",
								  ALLOCSET_DEFAULT_SIZES);

	/*
	 * initialize child nodes
	 *
	 * If we are hashing then the child plan does not need to handle REWIND
	 * efficiently; see ExecReScanSetOp.
	 */
	if (node->strategy == SETOP_HASHED)
		eflags &= ~EXEC_FLAG_REWIND;
	outerPlanState(setopstate) = ExecInitNode(outerPlan(node), estate, eflags);
	outerDesc = ExecGetResultType(outerPlanState(setopstate));

	/*
	 * Initialize result slot and type. Setop nodes do no projections, so
	 * initialize projection info for this node appropriately.
	 */
	ExecInitResultTupleSlotTL(&setopstate->ps,
							  node->strategy == SETOP_HASHED ?
							  &TTSOpsMinimalTuple : &TTSOpsHeapTuple);
	setopstate->ps.ps_ProjInfo = NULL;

	/*
	 * Precompute fmgr lookup data for inner loop. We need both equality and
	 * hashing functions to do it by hashing, but only equality if not
	 * hashing.
	 */
	if (node->strategy == SETOP_HASHED)
		execTuplesHashPrepare(node->numCols,
							  node->dupOperators,
							  &setopstate->eqfuncoids,
							  &setopstate->hashfunctions);
	else
		setopstate->eqfunction =
			execTuplesMatchPrepare(outerDesc,
								   node->numCols,
								   node->dupColIdx,
								   node->dupOperators,
								   &setopstate->ps);

	if (node->strategy == SETOP_HASHED)
	{
		build_hash_table(setopstate);
		setopstate->table_filled = false;
	}
	else
	{
		setopstate->pergroup =
			(SetOpStatePerGroup) palloc0(sizeof(SetOpStatePerGroupData));
	}

	return setopstate;
}