예제 #1
0
파일: nterm.c 프로젝트: rforge/muste
void muste_nterm(int argc, char *argv[])
  {
  int i;
/*
  if (argc==1)
      {
      Rprintf("This program can be used as a SURVO 84C module only.");
      return;
      }
*/      
  s_init(argv[1]);

  i=init_sequence();
  if (i<0) { s_end(argv[1]); return; }
  i=init_regressors();
  if (i<0) return;

  i=linear_regression(seq_n,10);
  if (i<0) return;

  data_close(&data);

  edwrite(nterm_output_buffer,nterm_output_line,1);

  s_end(argv[1]);
}
예제 #2
0
Datum
currval_oid(PG_FUNCTION_ARGS)
{
	Oid			relid = PG_GETARG_OID(0);
	int64		result;
	SeqTable	elm;
	Relation	seqrel;

	/* open and AccessShareLock sequence */
	init_sequence(relid, &elm, &seqrel);

	if (pg_class_aclcheck(elm->relid, GetUserId(),
						  ACL_SELECT | ACL_USAGE) != ACLCHECK_OK)
		ereport(ERROR,
				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
				 errmsg("permission denied for sequence %s",
						RelationGetRelationName(seqrel))));

	if (!elm->last_valid)
		ereport(ERROR,
				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
				 errmsg("currval of sequence \"%s\" is not yet defined in this session",
						RelationGetRelationName(seqrel))));

	result = elm->last;

	relation_close(seqrel, NoLock);

	PG_RETURN_INT64(result);
}
예제 #3
0
int write_sequence_to_sequences (FEATURE_TABLE *feature_table, 
				 char *seq, 
				 char *identifier, 
				 int seq_len)
{
    SEQUENCE *s;
    int num_seq;
       
    num_seq = sequences->num_seq;
    if (NULL == ( s = init_sequence())) return -1;
    /*if (NULL == (s->seq = (char *)xmalloc((seq_len+1)*sizeof(char))))	
	return -1;
	strcpy (s->seq, seq);*/
    s->seq = seq;
    s->name = strdup (identifier);
    s->length = seq_len;
    s->start = 1;
    s->end = seq_len;
    s->type = get_seq_type (seq, seq_len);
    s->feature_table = feature_table;
    s->id = num_seq;
 
    if (num_seq != 0) {
	sequences = realloc_sequences (sequences, num_seq);
    }
    sequences->sequence[num_seq] = s;
    sequences->num_seq ++;
   
    add_reg_seq(num_seq);

    return 0;
}
예제 #4
0
int ddrinit(void)
{
	printf("Initializing DDR SDRAM...\n");
	
	init_sequence();
	dfii_control_write(DFII_CONTROL_SEL|DFII_CONTROL_CKE);
	if(!memtest())
		return 0;
	
	return 1;
}
예제 #5
0
/*
 * Reset a sequence to its initial value.
 *
 * The change is made transactionally, so that on failure of the current
 * transaction, the sequence will be restored to its previous state.
 * We do that by creating a whole new___ relfilenode for the sequence; so this
 * works much like the rewriting forms of ALTER TABLE.
 *
 * Caller is assumed to have acquired AccessExclusiveLock on the sequence,
 * which must not be released until end of transaction.  Caller is also
 * responsible for permissions checking.
 */
void
ResetSequence(Oid seq_relid)
{
	Relation	seq_rel;
	SeqTable	elm;
	Form_pg_sequence seq;
	Buffer		buf;
	HeapTupleData seqtuple;
	HeapTuple	tuple;

	/*
	 * Read the old sequence.  This does a bit more work than really
	 * necessary, but it's simple, and we do want to double-check that it's
	 * indeed a sequence.
	 */
	init_sequence(seq_relid, &elm, &seq_rel);
	(void) read_seq_tuple(elm, seq_rel, &buf, &seqtuple);

	/*
	 * Copy the existing sequence tuple.
	 */
	tuple = heap_copytuple(&seqtuple);

	/* Now we're done with the old page */
	UnlockReleaseBuffer(buf);

	/*
	 * Modify the copied tuple to execute the restart (compare the RESTART
	 * action in AlterSequence)
	 */
	seq = (Form_pg_sequence) GETSTRUCT(tuple);
	seq->last_value = seq->start_value;
	seq->is_called = false;
	seq->log_cnt = 0;

	/*
	 * Create a new___ storage file for the sequence.  We want to keep the
	 * sequence's relfrozenxid at 0, since it won't contain any unfrozen XIDs.
	 * Same with relminmxid, since a sequence will never contain multixacts.
	 */
	RelationSetNewRelfilenode(seq_rel, seq_rel->rd_rel->relpersistence,
							  InvalidTransactionId, InvalidMultiXactId);

	/*
	 * Insert the modified tuple into the new___ storage file.
	 */
	fill_seq_with_data(seq_rel, tuple);

	/* Clear local cache so that we don't think we have cached numbers */
	/* Note that we do not change the currval() state */
	elm->cached = elm->last;

	relation_close(seq_rel, NoLock);
}
예제 #6
0
파일: sdram.c 프로젝트: rohit91/misoc
int sdrinit(void)
{
	printf("Initializing SDRAM...\n");

	init_sequence();
#ifdef CSR_DDRPHY_BASE
	if(!sdrlevel())
		return 0;
#endif
	sdram_dfii_control_write(DFII_CONTROL_SEL);
	if(!memtest())
		return 0;

	return 1;
}
예제 #7
0
/*
**policy_handler select the corresponding function to handle the request sequence
**@ncylinder is the total number of cylinders
**@ipolicy is the index if policy
**@ifile is the file pointer to the input_file
**@result is a pointer to dynamic array for store execute sequence and their travel_num
**@travel is the total travel number
*/
void policy_handler(int ncylinder, int ipolicy, FILE *ifile, int **result, int *travel)
{
	int *list = NULL;
	init_sequence(ncylinder, ifile, &list);
	init_result(result);
	item *sorted = NULL;
	int first = list[0];

	//sort the request according to there distance to the head of disk
	if (ipolicy == 2 || ipolicy == 3 || ipolicy == 4)
		 sorted = sort(ncylinder, list);
	if (ipolicy == 1)
		*travel = fcfs(ncylinder, list, *result);
	else if (ipolicy == 2)
		*travel = sstf(first, sorted, *result);
	else if (ipolicy == 3)
		*travel = cscan(ncylinder, first, sorted, *result);
	else if (ipolicy == 4)
		*travel = look(ncylinder, first, sorted, *result);

}
예제 #8
0
int main(int argc, char **argv) {
  int i;
  sequence_t seq;
  char *input_b, *scrambled_b;
  float *input_f, *scrambled_f;

  parse_args(argc, argv);

  if (init_sequence(&seq, sequence_name) == -1) {
    fprintf(stderr, "Error initiating sequence %s\n", sequence_name);
    exit(-1);
  }

  if (!do_floats) {
    input_b = malloc(sizeof(char) * seq.len);
    if (!input_b) {
      perror("malloc");
      exit(-1);
    }
    scrambled_b = malloc(sizeof(char) * seq.len);
    if (!scrambled_b) {
      perror("malloc");
      exit(-1);
    }

    for (i=0;i<seq.len;i++) {
      input_b[i] = rand()%2;
      scrambled_b[i] = input_b[i];
    }

    scrambling_b(&seq, scrambled_b);
    scrambling_b(&seq, scrambled_b);

    for (i=0;i<seq.len;i++) {
      if (scrambled_b[i] != input_b[i]) {
        printf("Error in %d\n", i);
        exit(-1);
      }
    }
    free(input_b);
    free(scrambled_b);
  } else {
    input_f = malloc(sizeof(float) * seq.len);
    if (!input_f) {
      perror("malloc");
      exit(-1);
    }
    scrambled_f = malloc(sizeof(float) * seq.len);
    if (!scrambled_f) {
      perror("malloc");
      exit(-1);
    }

    for (i=0;i<seq.len;i++) {
      input_f[i] = 100*(rand()/RAND_MAX);
      scrambled_f[i] = input_f[i];
    }

    scrambling_f(&seq, scrambled_f);
    scrambling_f(&seq, scrambled_f);

    for (i=0;i<seq.len;i++) {
      if (scrambled_f[i] != input_f[i]) {
        printf("Error in %d\n", i);
        exit(-1);
      }
    }

    free(input_f);
    free(scrambled_f);
  }
  printf("Ok\n");
  sequence_free(&seq);
  exit(0);
}
예제 #9
0
int main(int argc, char **argv) {
  int i;
  srslte_sequence_t seq;
  uint8_t *input_b, *scrambled_b;
  float *input_f, *scrambled_f;
  struct timeval t[3];
  
  parse_args(argc, argv);

  if (init_sequence(&seq, srslte_sequence_name) == -1) {
    fprintf(stderr, "Error initiating sequence %s\n", srslte_sequence_name);
    exit(-1);
  }

  if (!do_floats) {
    input_b = malloc(sizeof(uint8_t) * seq.len);
    if (!input_b) {
      perror("malloc");
      exit(-1);
    }
    scrambled_b = malloc(sizeof(uint8_t) * seq.len);
    if (!scrambled_b) {
      perror("malloc");
      exit(-1);
    }

    for (i=0;i<seq.len;i++) {
      input_b[i] = rand()%2;
      scrambled_b[i] = input_b[i];
    }

    gettimeofday(&t[1], NULL);
    srslte_scrambling_b(&seq, scrambled_b);
    gettimeofday(&t[2], NULL);
    srslte_scrambling_b(&seq, scrambled_b);

    get_time_interval(t);
    printf("Texec=%d us for %d bits\n", t[0].tv_usec, seq.len);
    
    for (i=0;i<seq.len;i++) {
      if (scrambled_b[i] != input_b[i]) {
        printf("Error in %d\n", i);
        exit(-1);
      }
    }
    free(input_b);
    free(scrambled_b);
  } else {
    input_f = malloc(sizeof(float) * seq.len);
    if (!input_f) {
      perror("malloc");
      exit(-1);
    }
    scrambled_f = malloc(sizeof(float) * seq.len);
    if (!scrambled_f) {
      perror("malloc");
      exit(-1);
    }

    for (i=0;i<seq.len;i++) {
      input_f[i] = 100*(rand()/RAND_MAX);
      scrambled_f[i] = input_f[i];
    }

    gettimeofday(&t[1], NULL);
    srslte_scrambling_f(&seq, scrambled_f);
    gettimeofday(&t[2], NULL);
    srslte_scrambling_f(&seq, scrambled_f);

    get_time_interval(t);
    printf("Texec=%d us for %d bits\n", t[0].tv_usec, seq.len);

    for (i=0;i<seq.len;i++) {
      if (scrambled_f[i] != input_f[i]) {
        printf("Error in %d\n", i);
        exit(-1);
      }
    }

    free(input_f);
    free(scrambled_f);
  }
  printf("Ok\n");
  srslte_sequence_free(&seq);
  exit(0);
}
예제 #10
0
void
load_builtins()
{
    duplicate_rule( "Always" ,
      bind_builtin( "ALWAYS" ,
                    builtin_flags, T_FLAG_TOUCHED, 0 ) );

    duplicate_rule( "Depends" ,
      bind_builtin( "DEPENDS" ,
                    builtin_depends, 0, 0 ) );

    duplicate_rule( "echo" ,
    duplicate_rule( "Echo" ,
      bind_builtin( "ECHO" ,
                    builtin_echo, 0, 0 ) ) );


    {
        char * args[] = { "message", "*", ":", "result-value", "?", 0 };
        duplicate_rule( "exit" ,
        duplicate_rule( "Exit" ,
          bind_builtin( "EXIT" ,
                        builtin_exit, 0, args ) ) );
    }

    {
        char * args[] = { "directories", "*", ":", "patterns", "*", ":", "case-insensitive", "?", 0 };
        duplicate_rule(
            "Glob" ,
            bind_builtin( "GLOB" , builtin_glob, 0, args )
            );
    }

    {
        char * args[] = { "patterns", "*", 0 };
        bind_builtin( "GLOB-RECURSIVELY" , builtin_glob_recursive, 0, args );
    }


    duplicate_rule( "Includes" ,
      bind_builtin( "INCLUDES" ,
                    builtin_depends, 1, 0 ) );

    {
        char * args[] = { "targets", "*", ":", "targets-to-rebuild", "*", 0 };
        bind_builtin( "REBUILDS" ,
                      builtin_rebuilds, 0, args );
    }
    
    duplicate_rule( "Leaves" ,
      bind_builtin( "LEAVES" ,
                    builtin_flags, T_FLAG_LEAVES, 0 ) );

    duplicate_rule( "Match" ,
      bind_builtin( "MATCH" ,
                    builtin_match, 0, 0 ) );

    duplicate_rule( "NoCare" ,
      bind_builtin( "NOCARE" ,
                    builtin_flags, T_FLAG_NOCARE, 0 ) );

    duplicate_rule( "NOTIME" ,
    duplicate_rule( "NotFile" ,
      bind_builtin( "NOTFILE" ,
                    builtin_flags, T_FLAG_NOTFILE, 0 ) ) );

    duplicate_rule( "NoUpdate" ,
      bind_builtin( "NOUPDATE" ,
                    builtin_flags, T_FLAG_NOUPDATE, 0 ) );

    duplicate_rule( "Temporary" ,
      bind_builtin( "TEMPORARY" ,
                    builtin_flags, T_FLAG_TEMP, 0 ) );

    {
        char * args[] = { "targets", "*", 0 };
        bind_builtin(
            "ISFILE",
            builtin_flags, T_FLAG_ISFILE, 0 );
    }

    duplicate_rule( "HdrMacro" ,
      bind_builtin( "HDRMACRO" ,
                    builtin_hdrmacro, 0, 0 ) );

    /* FAIL_EXPECTED is used to indicate that the result of a target build */
    /* action should be inverted (ok <=> fail) this can be useful when     */
    /* performing test runs from Jamfiles..                                */
      bind_builtin( "FAIL_EXPECTED" ,
                    builtin_flags, T_FLAG_FAIL_EXPECTED, 0 );

      bind_builtin( "RMOLD" , builtin_flags, T_FLAG_RMOLD, 0 );
      
      {
          char * args[] = { "targets", "*", 0 };
          bind_builtin( "UPDATE", builtin_update, 0, args );
      }

      {
          char * args[] = { "string", "pattern", "replacements", "+", 0 };
          duplicate_rule( "subst" ,
            bind_builtin( "SUBST" ,
                          builtin_subst, 0, args ) );
      }

      {
          char * args[] = { "module", "?", 0 };
          bind_builtin( "RULENAMES" ,
                         builtin_rulenames, 0, args );
      }


      {
          char * args[] = { "module", "?", 0 };
          bind_builtin( "VARNAMES" ,
                         builtin_varnames, 0, args );
      }

      {
          char * args[] = { "module", "?", 0 };
          bind_builtin( "DELETE_MODULE" ,
                         builtin_delete_module, 0, args );
      }

      {
           char * args[] = { "source_module", "?",
                             ":", "source_rules", "*",
                             ":", "target_module", "?",
                             ":", "target_rules", "*",
                             ":", "localize", "?", 0 };
           bind_builtin( "IMPORT" ,
                         builtin_import, 0, args );
      }

      {
          char * args[] = { "module", "?", ":", "rules", "*", 0 };
          bind_builtin( "EXPORT" ,
                        builtin_export, 0, args );
      }

      {
          char * args[] = { "levels", "?", 0 };
          bind_builtin( "CALLER_MODULE" ,
                         builtin_caller_module, 0, args );
      }

      {
          char * args[] = { "levels", "?", 0 };
          bind_builtin( "BACKTRACE" ,
                        builtin_backtrace, 0, args );
      }

      {
          char * args[] = { 0 };
          bind_builtin( "PWD" ,
                        builtin_pwd, 0, args );
      }

      {
          char * args[] = { "target", "*", ":", "path", "*", 0 };
          bind_builtin( "SEARCH_FOR_TARGET",
                        builtin_search_for_target, 0, args );
      }

      {
          char * args[] = { "modules_to_import", "+", ":", "target_module", "?", 0 };
          bind_builtin( "IMPORT_MODULE",
                        builtin_import_module, 0, args );
      }

      {
          char * args[] = { "module", "?", 0 };
          bind_builtin( "IMPORTED_MODULES",
                        builtin_imported_modules, 0, args );
      }

      {
          char * args[] = { "instance_module", ":", "class_module", 0 };
          bind_builtin( "INSTANCE",
                        builtin_instance, 0, args );
      }

      {
          char * args[] = { "sequence", "*", 0 };
          bind_builtin( "SORT",
                        builtin_sort, 0, args );
      }

      {
          char * args[] = { "path_parts", "*", 0 };
          bind_builtin( "NORMALIZE_PATH",
              builtin_normalize_path, 0, args );
      }

      {
          char * args[] = { "args", "*", 0 };
          bind_builtin( "CALC",
              builtin_calc, 0, args );
      }

      {
          char * args[] = { "module", ":", "rule", 0 };
          bind_builtin( "NATIVE_RULE",
              builtin_native_rule, 0, args );
      }

      {
          char * args[] = { "module", ":", "rule", ":", "version", 0 };
          bind_builtin( "HAS_NATIVE_RULE",
              builtin_has_native_rule, 0, args );
      }


      {
          char * args[] = { "module", "*", 0 };
          bind_builtin( "USER_MODULE",
              builtin_user_module, 0, args );
      }

      {
          char * args[] = { 0 };
          bind_builtin( "NEAREST_USER_LOCATION",
              builtin_nearest_user_location, 0, args );
      }

      {
          char * args[] = { "file", 0 };
          bind_builtin( "CHECK_IF_FILE",
                        builtin_check_if_file, 0, args );
      }

#ifdef HAVE_PYTHON
      {
          char * args[] = { "python-module", ":", "function", ":", 
                            "jam-module", ":", "rule-name", 0 };
          bind_builtin( "PYTHON_IMPORT_RULE",
              builtin_python_import_rule, 0, args );
      }
#endif

# if defined( OS_NT ) || defined( OS_CYGWIN )
      {
          char * args[] = { "key_path", ":", "data", "?", 0 };
          bind_builtin( "W32_GETREG",
              builtin_system_registry, 0, args );
      }

      {
          char * args[] = { "key_path", ":", "result-type", 0 };
          bind_builtin( "W32_GETREGNAMES",
              builtin_system_registry_names, 0, args );
      }
# endif

      {
          char * args[] = { "command", ":", "*", 0 };
          bind_builtin( "SHELL",
              builtin_shell, 0, args );
          bind_builtin( "COMMAND",
              builtin_shell, 0, args );
      }

      /* Initialize builtin modules */
      init_set();
      init_path();
      init_regex();
      init_property_set();
      init_sequence();
      init_order();
}
예제 #11
0
/*
 * Main internal procedure that handles 2 & 3 arg forms of SETVAL.
 *
 * Note that the 3 arg version (which sets the is_called flag) is
 * only for use in pg_dump, and setting the is_called flag may not
 * work if multiple users are attached to the database and referencing
 * the sequence (unlikely if pg_dump is restoring it).
 *
 * It is necessary to have the 3 arg version so that pg_dump can
 * restore the state of a sequence exactly during data-only restores -
 * it is the only way to clear the is_called flag in an existing
 * sequence.
 */
static void
do_setval(Oid relid, int64 next, bool iscalled)
{
	SeqTable	elm;
	Relation	seqrel;
	Buffer		buf;
	HeapTupleData seqtuple;
	Form_pg_sequence seq;

	/* open and AccessShareLock sequence */
	init_sequence(relid, &elm, &seqrel);

	if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
		ereport(ERROR,
				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
				 errmsg("permission denied for sequence %s",
						RelationGetRelationName(seqrel))));

	/* read-only transactions may only modify temp sequences */
	if (!seqrel->rd_islocaltemp)
		PreventCommandIfReadOnly("setval()");

	/*
	 * Forbid this during parallel operation because, to make it work,
	 * the cooperating backends would need to share the backend-local cached
	 * sequence information.  Currently, we don't support that.
	 */
	PreventCommandIfParallelMode("setval()");

	/* lock page' buffer and read tuple */
	seq = read_seq_tuple(elm, seqrel, &buf, &seqtuple);

	if ((next < seq->min_value) || (next > seq->max_value))
	{
		char		bufv[100],
					bufm[100],
					bufx[100];

		snprintf(bufv, sizeof(bufv), INT64_FORMAT, next);
		snprintf(bufm, sizeof(bufm), INT64_FORMAT, seq->min_value);
		snprintf(bufx, sizeof(bufx), INT64_FORMAT, seq->max_value);
		ereport(ERROR,
				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
				 errmsg("setval: value %s is out of bounds for sequence \"%s\" (%s..%s)",
						bufv, RelationGetRelationName(seqrel),
						bufm, bufx)));
	}

	/* Set the currval() state only if iscalled = true */
	if (iscalled)
	{
		elm->last = next;		/* last returned number */
		elm->last_valid = true;
	}

	/* In any case, forget any future cached numbers */
	elm->cached = elm->last;

	/* check the comment above nextval_internal()'s equivalent call. */
	if (RelationNeedsWAL(seqrel))
		GetTopTransactionId();

	/* ready to change the on-disk (or really, in-buffer) tuple */
	START_CRIT_SECTION();

	seq->last_value = next;		/* last fetched number */
	seq->is_called = iscalled;
	seq->log_cnt = 0;

	MarkBufferDirty(buf);

	/* XLOG stuff */
	if (RelationNeedsWAL(seqrel))
	{
		xl_seq_rec	xlrec;
		XLogRecPtr	recptr;
		Page		page = BufferGetPage(buf);

		XLogBeginInsert();
		XLogRegisterBuffer(0, buf, REGBUF_WILL_INIT);

		xlrec.node = seqrel->rd_node;
		XLogRegisterData((char *) &xlrec, sizeof(xl_seq_rec));
		XLogRegisterData((char *) seqtuple.t_data, seqtuple.t_len);

		recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG);

		PageSetLSN(page, recptr);
	}

	END_CRIT_SECTION();

	UnlockReleaseBuffer(buf);

	relation_close(seqrel, NoLock);
}
예제 #12
0
static int64
nextval_internal(Oid relid)
{
	SeqTable	elm;
	Relation	seqrel;
	Buffer		buf;
	Page		page;
	HeapTupleData seqtuple;
	Form_pg_sequence seq;
	int64		incby,
				maxv,
				minv,
				cache,
				log,
				fetch,
				last;
	int64		result,
				next,
				rescnt = 0;
	bool		logit = false;

	/* open and AccessShareLock sequence */
	init_sequence(relid, &elm, &seqrel);

	if (pg_class_aclcheck(elm->relid, GetUserId(),
						  ACL_USAGE | ACL_UPDATE) != ACLCHECK_OK)
		ereport(ERROR,
				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
				 errmsg("permission denied for sequence %s",
						RelationGetRelationName(seqrel))));

	/* read-only transactions may only modify temp sequences */
	if (!seqrel->rd_islocaltemp)
		PreventCommandIfReadOnly("nextval()");

	/*
	 * Forbid this during parallel operation because, to make it work,
	 * the cooperating backends would need to share the backend-local cached
	 * sequence information.  Currently, we don't support that.
	 */
	PreventCommandIfParallelMode("nextval()");

	if (elm->last != elm->cached)		/* some numbers were cached */
	{
		Assert(elm->last_valid);
		Assert(elm->increment != 0);
		elm->last += elm->increment;
		relation_close(seqrel, NoLock);
		last_used_seq = elm;
		return elm->last;
	}

	/* lock page' buffer and read tuple */
	seq = read_seq_tuple(elm, seqrel, &buf, &seqtuple);
	page = BufferGetPage(buf);

	last = next = result = seq->last_value;
	incby = seq->increment_by;
	maxv = seq->max_value;
	minv = seq->min_value;
	fetch = cache = seq->cache_value;
	log = seq->log_cnt;

	if (!seq->is_called)
	{
		rescnt++;				/* return last_value if not is_called */
		fetch--;
	}

	/*
	 * Decide whether we should emit a WAL log record.  If so, force up the
	 * fetch count to grab SEQ_LOG_VALS more values than we actually need to
	 * cache.  (These will then be usable without logging.)
	 *
	 * If this is the first nextval after a checkpoint, we must force a new___
	 * WAL record to be written anyway, else replay starting from the
	 * checkpoint would fail to advance the sequence past the logged values.
	 * In this case we may as well fetch extra values.
	 */
	if (log < fetch || !seq->is_called)
	{
		/* forced log to satisfy local demand for values */
		fetch = log = fetch + SEQ_LOG_VALS;
		logit = true;
	}
	else
	{
		XLogRecPtr	redoptr = GetRedoRecPtr();

		if (PageGetLSN(page) <= redoptr)
		{
			/* last update of seq was before checkpoint */
			fetch = log = fetch + SEQ_LOG_VALS;
			logit = true;
		}
	}

	while (fetch)				/* try to fetch cache [+ log ] numbers */
	{
		/*
		 * Check MAXVALUE for ascending sequences and MINVALUE for descending
		 * sequences
		 */
		if (incby > 0)
		{
			/* ascending sequence */
			if ((maxv >= 0 && next > maxv - incby) ||
				(maxv < 0 && next + incby > maxv))
			{
				if (rescnt > 0)
					break;		/* stop fetching */
				if (!seq->is_cycled)
				{
					char		buf[100];

					snprintf(buf, sizeof(buf), INT64_FORMAT, maxv);
					ereport(ERROR,
						  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
						   errmsg("nextval: reached maximum value of sequence \"%s\" (%s)",
								  RelationGetRelationName(seqrel), buf)));
				}
				next = minv;
			}
			else
				next += incby;
		}
		else
		{
			/* descending sequence */
			if ((minv < 0 && next < minv - incby) ||
				(minv >= 0 && next + incby < minv))
			{
				if (rescnt > 0)
					break;		/* stop fetching */
				if (!seq->is_cycled)
				{
					char		buf[100];

					snprintf(buf, sizeof(buf), INT64_FORMAT, minv);
					ereport(ERROR,
						  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
						   errmsg("nextval: reached minimum value of sequence \"%s\" (%s)",
								  RelationGetRelationName(seqrel), buf)));
				}
				next = maxv;
			}
			else
				next += incby;
		}
		fetch--;
		if (rescnt < cache)
		{
			log--;
			rescnt++;
			last = next;
			if (rescnt == 1)	/* if it's first result - */
				result = next;	/* it's what to return */
		}
	}

	log -= fetch;				/* adjust for any unfetched numbers */
	Assert(log >= 0);

	/* save info in local cache */
	elm->last = result;			/* last returned number */
	elm->cached = last;			/* last fetched number */
	elm->last_valid = true;

	last_used_seq = elm;

	/*
	 * If something needs to be WAL logged, acquire an xid, so this
	 * transaction's commit will trigger a WAL flush and wait for
	 * syncrep. It's sufficient to ensure the toplevel transaction has an xid,
	 * no need to assign xids subxacts, that'll already trigger an appropriate
	 * wait.  (Have to do that here, so we're outside the critical section)
	 */
	if (logit && RelationNeedsWAL(seqrel))
		GetTopTransactionId();

	/* ready to change the on-disk (or really, in-buffer) tuple */
	START_CRIT_SECTION();

	/*
	 * We must mark the buffer dirty before doing XLogInsert(); see notes in
	 * SyncOneBuffer().  However, we don't apply the desired changes just yet.
	 * This looks like a violation of the buffer update protocol, but it is in
	 * fact safe because we hold exclusive lock on the buffer.  Any other
	 * process, including a checkpoint, that tries to examine the buffer
	 * contents will block until we release the lock, and then will see the
	 * final state that we install below.
	 */
	MarkBufferDirty(buf);

	/* XLOG stuff */
	if (logit && RelationNeedsWAL(seqrel))
	{
		xl_seq_rec	xlrec;
		XLogRecPtr	recptr;

		/*
		 * We don't log the current state of the tuple, but rather the state
		 * as it would appear after "log" more fetches.  This lets us skip
		 * that many future WAL records, at the cost that we lose those
		 * sequence values if we crash.
		 */
		XLogBeginInsert();
		XLogRegisterBuffer(0, buf, REGBUF_WILL_INIT);

		/* set values that will be saved in xlog */
		seq->last_value = next;
		seq->is_called = true;
		seq->log_cnt = 0;

		xlrec.node = seqrel->rd_node;

		XLogRegisterData((char *) &xlrec, sizeof(xl_seq_rec));
		XLogRegisterData((char *) seqtuple.t_data, seqtuple.t_len);

		recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG);

		PageSetLSN(page, recptr);
	}

	/* Now update sequence tuple to the intended final state */
	seq->last_value = last;		/* last fetched number */
	seq->is_called = true;
	seq->log_cnt = log;			/* how much is logged */

	END_CRIT_SECTION();

	UnlockReleaseBuffer(buf);

	relation_close(seqrel, NoLock);

	return result;
}
예제 #13
0
/*
 * AlterSequence
 *
 * Modify the definition of a sequence relation
 */
ObjectAddress
AlterSequence(AlterSeqStmt *stmt)
{
	Oid			relid;
	SeqTable	elm;
	Relation	seqrel;
	Buffer		buf;
	HeapTupleData seqtuple;
	Form_pg_sequence seq;
	FormData_pg_sequence new___;
	List	   *owned_by;
	ObjectAddress address;

	/* Open and lock sequence. */
	relid = RangeVarGetRelid(stmt->sequence, AccessShareLock, stmt->missing_ok);
	if (relid == InvalidOid)
	{
		ereport(NOTICE,
				(errmsg("relation \"%s\" does not exist, skipping",
						stmt->sequence->relname)));
		return InvalidObjectAddress;
	}

	init_sequence(relid, &elm, &seqrel);

	/* allow ALTER to sequence owner only */
	if (!pg_class_ownercheck(relid, GetUserId()))
		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
					   stmt->sequence->relname);

	/* lock page' buffer and read tuple into new___ sequence structure */
	seq = read_seq_tuple(elm, seqrel, &buf, &seqtuple);

	/* Copy old values of options into workspace */
	memcpy(&new___, seq, sizeof(FormData_pg_sequence));

	/* Check and set new___ values */
	init_params(stmt->options, false, &new___, &owned_by);

	/* Clear local cache so that we don't think we have cached numbers */
	/* Note that we do not change the currval() state */
	elm->cached = elm->last;

	/* check the comment above nextval_internal()'s equivalent call. */
	if (RelationNeedsWAL(seqrel))
		GetTopTransactionId();

	/* Now okay to update the on-disk tuple */
	START_CRIT_SECTION();

	memcpy(seq, &new___, sizeof(FormData_pg_sequence));

	MarkBufferDirty(buf);

	/* XLOG stuff */
	if (RelationNeedsWAL(seqrel))
	{
		xl_seq_rec	xlrec;
		XLogRecPtr	recptr;
		Page		page = BufferGetPage(buf);

		XLogBeginInsert();
		XLogRegisterBuffer(0, buf, REGBUF_WILL_INIT);

		xlrec.node = seqrel->rd_node;
		XLogRegisterData((char *) &xlrec, sizeof(xl_seq_rec));

		XLogRegisterData((char *) seqtuple.t_data, seqtuple.t_len);

		recptr = XLogInsert(RM_SEQ_ID, XLOG_SEQ_LOG);

		PageSetLSN(page, recptr);
	}

	END_CRIT_SECTION();

	UnlockReleaseBuffer(buf);

	/* process OWNED BY if given */
	if (owned_by)
		process_owned_by(seqrel, owned_by);

	InvokeObjectPostAlterHook(RelationRelationId, relid, 0);

	ObjectAddressSet(address, RelationRelationId, relid);

	relation_close(seqrel, NoLock);

	return address;
}