示例#1
0
文件: c_example.c 项目: h0st/m3sec
int main() 
{
  DB *dbp;
  DBT key, data;
  int ret, t_ret;

  if ((ret = db_create(&dbp, NULL, 0)) != 0) 
  {
    cerr << "db_create:" << db_strerror(ret) << endl;
    exit (1);
  }

  if ((ret = dbp->open(dbp, NULL, kDatabaseName, "",
                       DB_BTREE, DB_CREATE, 0664)) != 0) 
  {
    dbp->err(dbp, ret, "%s", kDatabaseName);
    goto err;
  }

  memset(&key, 0, sizeof(key));
  memset(&data, 0, sizeof(data));
  key.data = (char*)"fruit";
  key.size = sizeof("fruit");
  data.data = (char*)"apple";
  data.size = sizeof("apple");

  if ((ret = dbp->put(dbp, NULL, &key, &data, 0)) == 0)
    cout << "db: " << (char*)key.data << ": key stored.\n";
  else 
  {
    dbp->err(dbp, ret, "DB->put");
    goto err;
  }

  if ((ret = dbp->get(dbp, NULL, &key, &data, 0)) == 0)
    cout << "db: " << (char*)key.data
         << ": key retrieved: data was " << (char *)data.data << endl;
  else 
  {
    dbp->err(dbp, ret, "DB->get");
    goto err;
  }

  if ((ret = dbp->del(dbp, NULL, &key, 0)) == 0)
    cout << "db: " << (char*)key.data << " key was deleted.\n";
  else 
  {
    dbp->err(dbp, ret, "DB->del");
    goto err;
  }

  if ((ret = dbp->get(dbp, NULL, &key, &data, 0)) == 0)
    cout << "db: " << (char*)key.data << ": key retrieved: data was "
         << (char *)data.data << endl;
  else
    dbp->err(dbp, ret, "DB->get");

err:
  if ((t_ret = dbp->close(dbp, 0)) != 0 && ret == 0)
    ret = t_ret;

  return ret;
}
示例#2
0
int
b_load(int argc, char *argv[])
{
	extern char *optarg;
	extern int optind;
	DB *dbp;
	DBTYPE type;
	DBT key, data;
#if DB_VERSION_MAJOR > 5 || (DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR >= 2)
	DB_HEAP_RID rid;
#endif
	db_recno_t recno;
	u_int32_t cachesize;
	int ch, i, count, duplicate;
	char *ts, buf[32];

	type = DB_BTREE;
	cachesize = MEGABYTE;
	count = 100000;
	duplicate = 0;
	ts = "Btree";
	while ((ch = getopt(argc, argv, "C:c:dt:")) != EOF)
		switch (ch) {
		case 'C':
			cachesize = (u_int32_t)atoi(optarg);
			break;
		case 'c':
			count = atoi(optarg);
			break;
		case 'd':
			duplicate = 1;
			break;
		case 't':
			switch (optarg[0]) {
			case 'B': case 'b':
				ts = "Btree";
				type = DB_BTREE;
				break;
			case 'H': case 'h':
				if (optarg[1] == 'E' || optarg[1] == 'e') {
#if DB_VERSION_MAJOR > 5 || (DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR >= 2)
					if (b_util_have_heap())
						return (0);
					ts = "Heap";
					type = DB_HEAP;
#else
					fprintf(stderr,
				"b_curwalk: Heap is not supported! \n");
					return (EXIT_SUCCESS);
#endif
				} else {
					if (b_util_have_hash())
						return (0);
					ts = "Hash";
					type = DB_HASH;
				}
				break;
			case 'Q': case 'q':
				if (b_util_have_queue())
					return (0);
				ts = "Queue";
				type = DB_QUEUE;
				break;
			case 'R': case 'r':
				ts = "Recno";
				type = DB_RECNO;
				break;
			default:
				return (usage());
			}
			break;
		case '?':
		default:
			return (usage());
		}
	argc -= optind;
	argv += optind;
	if (argc != 0)
		return (usage());

	/* Usage. */
#if DB_VERSION_MAJOR > 5 || (DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR >= 2)
	if (duplicate && 
	    (type == DB_QUEUE || type == DB_RECNO || type == DB_HEAP)) {
		fprintf(stderr,
	"b_load: Queue, Recno and Heap don't support duplicates\n");
		return (usage());
	}
#else
	if (duplicate && (type == DB_QUEUE || type == DB_RECNO)) {
		fprintf(stderr,
		    "b_load: Queue an Recno don't support duplicates\n");
		return (usage());
	}
#endif

#if DB_VERSION_MAJOR < 3 || DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR < 1
	/*
	 * DB versions prior to 3.1.17 didn't have off-page duplicates, so
	 * this test can run forever.
	 */
	if (duplicate)
		return (0);
#endif

	/* Create the database. */
	DB_BENCH_ASSERT(db_create(&dbp, NULL, 0) == 0);
	DB_BENCH_ASSERT(dbp->set_cachesize(dbp, 0, cachesize, 0) == 0);
	if (duplicate)
		DB_BENCH_ASSERT(dbp->set_flags(dbp, DB_DUP) == 0);
	dbp->set_errfile(dbp, stderr);

	/* Set record length for Queue. */
	if (type == DB_QUEUE)
		DB_BENCH_ASSERT(dbp->set_re_len(dbp, 20) == 0);

#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
	DB_BENCH_ASSERT(
	    dbp->open(dbp, NULL, TESTFILE, NULL, type, DB_CREATE, 0666) == 0);
#else
	DB_BENCH_ASSERT(
	    dbp->open(dbp, TESTFILE, NULL, type, DB_CREATE, 0666) == 0);
#endif

	/* Initialize the data. */
	memset(&key, 0, sizeof(key));
	memset(&data, 0, sizeof(data));

	/* Insert count in-order key/data pairs. */
	TIMER_START;
	if (duplicate) {
		key.size = 10;
		key.data = "01234567890123456789";
		data.data = buf;
		data.size = 20;
		for (i = 0; i < count; ++i) {
			(void)snprintf(buf, sizeof(buf), "%020d", i);
			DB_BENCH_ASSERT(
			    dbp->put(dbp, NULL, &key, &data, 0) == 0);
		}
	} else {
		data.data = buf;
		data.size = 20;
		if (type == DB_BTREE || type == DB_HASH) {
			key.size = 10;
			key.data = buf;
			for (i = 0; i < count; ++i) {
				(void)snprintf(buf, sizeof(buf), "%010d", i);
				DB_BENCH_ASSERT(
				    dbp->put(dbp, NULL, &key, &data, 0) == 0);
			}
#if DB_VERSION_MAJOR > 5 || (DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR >= 2)
		} else if (type == DB_HEAP) {
			key.data = &rid;
			key.size = sizeof(rid);
			for (i = 0; i < count; ++i)
				DB_BENCH_ASSERT(dbp->put(dbp, 
				    NULL, &key, &data, DB_APPEND) == 0);
#endif
		} else {
			key.data = &recno;
			key.size = sizeof(recno);
			for (i = 0, recno = 1; i < count; ++i, ++recno)
				DB_BENCH_ASSERT(
				    dbp->put(dbp, NULL, &key, &data, 0) == 0);
		}
	}

	TIMER_STOP;

	printf("# %d %s database in-order put of 10/20 byte key/data %sitems\n",
	    count, ts, duplicate ? "duplicate " : "");
	TIMER_DISPLAY(count);

	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0);

	return (0);
}
示例#3
0
/*
 * Class:     jpwr_rt_Mh
 * Method:    getHistList
 * Signature: (Ljava/lang/String;Ljava/lang/String;ZZZZZZZZLjava/lang/String;Ljava/lang/String;)[Ljpwr/rt/MhrEvent;
 */
JNIEXPORT jobjectArray JNICALL Java_jpwr_rt_Hist_getHistList
(JNIEnv *env, jclass obj, jstring jstartTime, jstring jstopTime, jboolean jtypeInfo, jboolean jtypeInfoSuccess, jboolean jtypeAlarm, jboolean jtypeMaintenanceAlarm, jboolean jtypeSystemAlarm, jboolean jtypeUserAlarm1, jboolean jtypeUserAlarm2, jboolean jtypeUserAlarm3, jboolean jtypeUserAlarm4, jboolean jtypeReturn, jboolean jtypeAck, jboolean jprioA, jboolean jprioB, jboolean jprioC, jboolean jprioD, jstring jname, jstring jtext)
{
#ifdef PWRE_CONF_LIBDB_CXX
  const char *str;
  char *cstr_minTime;
  char *cstr_maxTime;
  char *cstr_eventName;
  char *cstr_eventText;

  DB *dataBaseP = NULL;
  pwr_tInt32 ret, sts;
  char dbName[200];

  pwr_tUInt32 nrOfEvents = 0;
  sEvent *eventp;
  DBT data, key;
  DBC *dbcp;
  deque<sEvent> evDeq;
  HistQuery query;
  jobjectArray jobjectArr = NULL;
  unsigned int i = 0;

  //find the class for MhrEvent[]
  jclass mhrEventArrCls = env->FindClass("jpwr/rt/MhrEvent");

  if(mhrEventArrCls == NULL)
  {
      printf("Hittade inte jpwr/rt/MhrEvent\n");
    return (jobjectArray)NULL;
  }

  
  //  printf("I get_hist_list\n");
  
  memset(&query, 0, sizeof(HistQuery));

  //translate the jstrings to char[]
  str = env->GetStringUTFChars( jstartTime, 0);
  cstr_minTime = (char *)str;  
  gdh_ConvertUTFstring( cstr_minTime, cstr_minTime);
  query.minTime_str = cstr_minTime;

  str = env->GetStringUTFChars( jstopTime, 0);
  cstr_maxTime = (char *)str;  
  gdh_ConvertUTFstring( cstr_maxTime, cstr_maxTime);
  query.maxTime_str = cstr_maxTime;

  str = env->GetStringUTFChars( jname, 0);
  cstr_eventName = (char *)str;  
  gdh_ConvertUTFstring( cstr_eventName, cstr_eventName);
  query.eventName_str = cstr_eventName;

  str = env->GetStringUTFChars( jtext, 0);
  cstr_eventText = (char *)str;  
  gdh_ConvertUTFstring( cstr_eventText, cstr_eventText);
  query.eventText_str = cstr_eventText;

  query.eventType_Ack = jtypeAck;
  query.eventType_Alarm = jtypeAlarm;
  query.eventType_MaintenanceAlarm = jtypeMaintenanceAlarm;
  query.eventType_SystemAlarm = jtypeSystemAlarm;
  query.eventType_UserAlarm1 = jtypeUserAlarm1;
  query.eventType_UserAlarm2 = jtypeUserAlarm2;
  query.eventType_UserAlarm3 = jtypeUserAlarm3;
  query.eventType_UserAlarm4 = jtypeUserAlarm4;
  query.eventType_Return = jtypeReturn;
  query.eventType_Info = jtypeInfo;
  query.eventType_InfoSuccess = jtypeInfoSuccess;
  query.eventPrio_A = jprioA;
  query.eventPrio_B = jprioB;
  query.eventPrio_C = jprioC;
  query.eventPrio_D = jprioD;

  //printf("I get_hist_list1\n");
  
  dcli_translate_filename( dbName, DATABASE);
  
  /*create the database if it's not already created*/
  if((ret = db_create(&dataBaseP, NULL, 0)) != 0)
  {
    /*error creating db-handle send the mess to errh, then exit*/
    printf("error db_create: %s\n", db_strerror(ret));
    printf(" Fel vid skapande av databashandtag avslutar\n");
    goto err;
  }
#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR > 0
  ret = dataBaseP->open(dataBaseP, NULL, dbName, NULL, DATABASETYPE, DB_RDONLY, 0);
#else
  ret = dataBaseP->open(dataBaseP, dbName, NULL, DATABASETYPE, DB_RDONLY, 0);
#endif

  if(ret != 0)
  {
    /*error opening/creating db send the mess to errh, then exit*/
    printf("error db_open: %s\n", db_strerror(ret));
    goto err;
  }

    
  /* Acquire a cursor for the database. */ 
  if ((ret = dataBaseP->cursor(dataBaseP, NULL, &dbcp, 0)) != 0) 
  {
    printf("error dataBaseP->cursor: %s\n", db_strerror(ret)); 
    goto err;
  }

  /* Initialize the key/data return pair. */
  memset(&key, 0, sizeof(key));
  memset(&data, 0, sizeof(data));
  
  if((ret = dbcp->c_get(dbcp, &key, &data, DB_FIRST)) == 0)
  {
    eventp = (sEvent *)data.data;
    sts = check_conditions(eventp, &query);
    if(sts == ERROR_TIME_CONVERT)
    {
      printf("Error trying to convert userinput in time-field 1\n");
    }
    else if(ODD(sts))
    {
      nrOfEvents++;
      evDeq.push_front((sEvent)*eventp);
    }
    
      
  }
  
  while((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) == 0)
  {
    eventp = (sEvent *)data.data;
    sts = check_conditions(eventp, &query);
    if(sts == ERROR_TIME_CONVERT)
    {
      printf("Error trying to convert userinput in time-field\n");
    }
    else if(ODD(sts))
    {
      nrOfEvents++;
      evDeq.push_front(*eventp);
    }
  }
  if(ret != DB_NOTFOUND)
  {
    printf("error dbcp->c_get: %s\n", db_strerror(ret));
    printf("Fel vid försök att läsa post nr %u, avslutar\n", nrOfEvents);
  }

  /*Close the cursor*/
  if((ret = dbcp->c_close(dbcp)) != 0)
  {
    printf("Error dbcp->c_close(): %s\n", db_strerror(ret));
  }
  /*close the database*/  

  if((ret = dataBaseP->close(dataBaseP,0) != 0))
  {
    printf("error db_close: %s\n", db_strerror(ret));
  }


  //create a new MhrEvent[]
  jobjectArr = (jobjectArray)env->NewObjectArray(nrOfEvents, mhrEventArrCls, NULL);
  
  // printf("nrOfEvents: %d\n", nrOfEvents);
  sEvent ev;
  //put the result in an objectarray of MhrEvent
  for(i=0;i<nrOfEvents;i++)
  {
    ev = evDeq.front();
    
    switch (ev.EventType) {
      case mh_eEvent_Alarm:
      case mh_eEvent_MaintenanceAlarm:
      case mh_eEvent_SystemAlarm:
      case mh_eEvent_UserAlarm1:
      case mh_eEvent_UserAlarm2:
      case mh_eEvent_UserAlarm3:
      case mh_eEvent_UserAlarm4:
      case mh_eEvent_Info:
      case mh_eEvent_InfoSuccess:
        env->SetObjectArrayElement(jobjectArr, i, convertAlarmOrInfoToMhrEvent( (mh_sMessage *)(&(ev.Mess) ) ) );
        //printMess(sp, outFile);
      break;
      case mh_eEvent_Ack:
        env->SetObjectArrayElement(jobjectArr, i, convertAckToMhrEvent( (mh_sAck *)(&(ev.Mess) ) ) );
        //printAck(sp, outFile);
      break;
      case mh_eEvent_Cancel:
      case mh_eEvent_Return:
        env->SetObjectArrayElement(jobjectArr, i, convertReturnToMhrEvent( (mh_sReturn *)(&(ev.Mess) ) ) );
        //printRet(sp, outFile);
      break;
      case mh_eEvent_Block:
      case mh_eEvent_Unblock:
      case mh_eEvent_Reblock:
      case mh_eEvent_CancelBlock:
        env->SetObjectArrayElement(jobjectArr, i, NULL);
        //printBlock(sp, outFile);
      break;
      default:
        printf("histlist: Error in Write unknown EventType");
      break;

    }  
      evDeq.pop_front();
  }

err:
  env->ReleaseStringUTFChars( jstartTime, cstr_minTime );
  env->ReleaseStringUTFChars( jstopTime, cstr_maxTime );
  env->ReleaseStringUTFChars( jname, cstr_eventName );
  env->ReleaseStringUTFChars( jtext, cstr_eventText );
  return jobjectArr;
#else
  printf( "** Hist server not built with BerkeleyDB\n");
  return 0;
#endif
}
示例#4
0
int
b_open(int argc, char *argv[])
{
	extern char *optarg;
	extern int optind, __db_getopt_reset;
	DB_ENV *dbenv;
	DB *dbp;
	DBTYPE type;
	int ch, i, count;
	char *fname, *dbname, *ts;

	type = DB_BTREE;
	count = 1000;
	fname = dbname = NULL;
	ts = "Btree";
	__db_getopt_reset = 1;
	while ((ch = getopt(argc, argv, "c:dft:")) != EOF)
		switch (ch) {
		case 'c':
			count = atoi(optarg);
			break;
		case 'd':
			dbname = "dbname";
			break;
		case 'f':
			fname = "filename";
			break;
		case 't':
			switch (optarg[0]) {
			case 'B': case 'b':
				ts = "Btree";
				type = DB_BTREE;
				break;
			case 'H': case 'h':
				if (b_util_have_hash())
					return (0);
				ts = "Hash";
				type = DB_HASH;
				break;
			case 'Q': case 'q':
				if (b_util_have_queue())
					return (0);
				ts = "Queue";
				type = DB_QUEUE;
				break;
			case 'R': case 'r':
				ts = "Recno";
				type = DB_RECNO;
				break;
			default:
				return (b_open_usage());
			}
			break;
		case '?':
		default:
			return (b_open_usage());
		}
	argc -= optind;
	argv += optind;
	if (argc != 0)
		return (b_open_usage());

#if DB_VERSION_MAJOR < 4
	/*
	 * Don't run in-memory database tests on versions less than 3, it
	 * takes forever and eats memory.
	 */
	if (fname == NULL && dbname == NULL)
		return (0);
#endif
#if DB_VERSION_MAJOR < 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 4
	/*
	 * Named in-memory databases weren't available until 4.4.
	 */
	if (fname == NULL && dbname != NULL)
		return (0);
#endif

	/* Create the environment. */
	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0);
	dbenv->set_errfile(dbenv, stderr);
#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0
	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR,
	    NULL, DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE, 0666) == 0);
#else
	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR,
	    DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE, 0666) == 0);
#endif

	/* Create the database. */
	DB_BENCH_ASSERT(db_create(&dbp, dbenv, 0) == 0);

#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1
	DB_BENCH_ASSERT(dbp->open(
	    dbp, NULL, fname, dbname, type, DB_CREATE, 0666) == 0);
#else
	DB_BENCH_ASSERT(dbp->open(
	    dbp, fname, dbname, type, DB_CREATE, 0666) == 0);
#endif
	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0);

	/* Open the database count times. */
	TIMER_START;
	for (i = 0; i < count; ++i) {
		DB_BENCH_ASSERT(db_create(&dbp, dbenv, 0) == 0);
#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1
		DB_BENCH_ASSERT(dbp->open(
		    dbp, NULL, fname, dbname, type, DB_CREATE, 0666) == 0);
#else
		DB_BENCH_ASSERT(dbp->open(
		    dbp, fname, dbname, type, DB_CREATE, 0666) == 0);
#endif
		DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0);
	}
	TIMER_STOP;

	printf("# %d %s %sdatabase open/close pairs\n",
	    count, ts,
	    fname == NULL ?
		(dbname == NULL ? "in-memory " : "named in-memory ") :
		(dbname == NULL ? "" : "sub-"));
	TIMER_DISPLAY(count);

	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0);

	return (0);
}
示例#5
0
int
doloop(DB_ENV *dbenv)
{
    DB *dbp;
    APP_DATA *app_data;
    DBT key, data;
    char buf[BUFSIZE], *rbuf;
    int ret;
    u_int32_t flags;

    dbp = NULL;
    ret = 0;
    memset(&key, 0, sizeof(key));
    memset(&data, 0, sizeof(data));
    app_data = dbenv->app_private;

    for (;;) {
	if (dbp == NULL) {
	    if ((ret = db_create(&dbp, dbenv, 0)) != 0)
		return (ret);

	    flags = DB_AUTO_COMMIT;
	    if (app_data->is_master)
		flags |= DB_CREATE;
	    if ((ret = dbp->open(dbp,
		NULL, DATABASE, NULL, DB_BTREE, flags, 0)) != 0) {
		if (ret == ENOENT) {
		    printf(
		      "No stock database yet available.\n");
		    if ((ret = dbp->close(dbp, 0)) != 0) {
			dbenv->err(dbenv, ret, "DB->close");
			goto err;
		    }
		    dbp = NULL;
		    sleep(SLEEPTIME);
		    continue;
		}
		dbenv->err(dbenv, ret, "DB->open");
		goto err;
	    }
	}

	printf("QUOTESERVER%s> ",
	    app_data->is_master ? "" : " (read-only)");
	fflush(stdout);

	if (fgets(buf, sizeof(buf), stdin) == NULL)
	    break;
	if (strtok(&buf[0], " \t\n") == NULL) {
	    switch ((ret = print_stocks(dbp))) {
	    case 0:
		continue;
	    case DB_REP_HANDLE_DEAD:
		(void)dbp->close(dbp, DB_NOSYNC);
		dbp = NULL;
                dbenv->errx(dbenv, "Got a dead replication handle");
		continue;
	    default:
		dbp->err(dbp, ret, "Error traversing data");
		goto err;
	    }
	}
	rbuf = strtok(NULL, " \t\n");
	if (rbuf == NULL || rbuf[0] == '\0') {
	    if (strncmp(buf, "exit", 4) == 0 ||
		strncmp(buf, "quit", 4) == 0)
		break;
	    dbenv->errx(dbenv, "Format: TICKER VALUE");
	    continue;
	}

	if (!app_data->is_master) {
	    dbenv->errx(dbenv, "Can't update at client");
	    continue;
	}

	key.data = buf;
	key.size = (u_int32_t)strlen(buf);

	data.data = rbuf;
	data.size = (u_int32_t)strlen(rbuf);

	if ((ret = dbp->put(dbp,
	    NULL, &key, &data, 0)) != 0) {
	    dbp->err(dbp, ret, "DB->put");
	    goto err;
	}
    }

err: if (dbp != NULL)
	(void)dbp->close(dbp, DB_NOSYNC);

    return (ret);
}
示例#6
0
/**
 * The function is called to create a handle to a db table.
 * 
 * On startup, we do not create any of the db handles.
 * Instead it is done on first-use (lazy-initialized) to only create handles to 
 * files (db) that we require.
 * 
 * There is one db file per kamailio table (eg. acc), and they should exist
 * in your DB_PATH (refer to kamctlrc) directory.
 *
 * This function does _not_ create the underlying binary db tables.
 * Creating the tables MUST be manually performed before 
 * kamailio startup by 'kamdbctl create'
 *
 * Function returns NULL on error, which will cause kamailio to exit.
 *
 */
bdb_table_p bdblib_create_table(bdb_db_p _db, str *_s)
{

	int rc,i,flags;
	DB *bdb = NULL;
	bdb_table_p tp = NULL;
	char tblname[MAX_TABLENAME_SIZE]; 

	if(!_db || !_db->dbenv)
	{
		ERR("no bdb_db_p or dbenv.\n");
		return NULL;
	}

	tp = (bdb_table_p)pkg_malloc(sizeof(bdb_table_t));
	if(!tp)
	{
		ERR("no private memory for bdb_table_t.\n");
		return NULL;
	}

	if ((rc = db_create(&bdb, _db->dbenv, 0)) != 0)
	{ 
		_db->dbenv->err(_db->dbenv, rc, "database create");
		ERR("error in db_create, bdb error: %s.\n",db_strerror(rc));
		pkg_free(tp);
		return NULL;
	}

	memset(tblname, 0, MAX_TABLENAME_SIZE);
	strncpy(tblname, _s->s, _s->len);

	flags = DB_THREAD;

	if ((rc = bdb->open(bdb, NULL, tblname, NULL, DB_HASH, flags, 0664)) != 0)
	{ 
		_db->dbenv->err(_db->dbenv, rc, "DB->open: %s", tblname);
		ERR("bdb open failed: %s.\n",db_strerror(rc));
		pkg_free(tp);
		return NULL;
	}

	tp->name.s = (char*)pkg_malloc(_s->len*sizeof(char));
	memcpy(tp->name.s, _s->s, _s->len);
	tp->name.len = _s->len;
	tp->db=bdb;
	tp->ncols=0;
	tp->nkeys=0;
	tp->ro=0;    /*0=ReadWrite ; 1=ReadOnly*/
	tp->ino=0;   /*inode*/
	tp->logflags=0; /*bitmap; 4=Delete, 2=Update, 1=Insert, 0=None*/
	tp->fp=0;
	tp->t=0;
	
	for(i=0;i<MAX_NUM_COLS;i++)
		tp->colp[i] = NULL;

	/*load metadata; seeded\db_loaded when database are created*/
	
	/*initialize columns with metadata*/
	rc = load_metadata_columns(tp);
	if(rc!=0)
	{
		ERR("FAILED to load METADATA COLS in table: %s.\n", tblname);
		goto error;
	}
	
	/*initialize columns default values from metadata*/
	rc = load_metadata_defaults(tp);
	if(rc!=0)
	{
		ERR("FAILED to load METADATA DEFAULTS in table: %s.\n", tblname);
		goto error;
	}
	
	rc = load_metadata_keys(tp);
	if(rc!=0)
	{
		ERR("FAILED to load METADATA KEYS in table: %s.\n", tblname);
		/*will have problems later figuring column types*/
		goto error;
	}

	/*opened RW by default; Query to set the RO flag */
	rc = load_metadata_readonly(tp);
	if(rc!=0)
	{
		INFO("No METADATA_READONLY in table: %s.\n", tblname);
		/*non-critical; table will default to READWRITE*/
	}

	if(tp->ro)
	{	
		/*schema defines this table RO readonly*/
		
		if ((rc = bdb->close(bdb,0)) != 0)
		{ 
			_db->dbenv->err(_db->dbenv, rc, "DB->close: %s", tblname);
			ERR("bdb close: %s.\n",db_strerror(rc));
			goto error;
		}
		
		bdb = NULL;
		if ((rc = db_create(&bdb, _db->dbenv, 0)) != 0)
		{ 
			_db->dbenv->err(_db->dbenv, rc, "database create");
			ERR("error in db_create.\n");
			goto error;
		}
		
		flags = DB_THREAD | DB_RDONLY;
		if ((rc = bdb->open(bdb, NULL, tblname, NULL, DB_HASH, flags, 0664)) != 0)
		{ 
			_db->dbenv->err(_db->dbenv, rc, "DB->open: %s", tblname);
			ERR("bdb open: %s.\n",db_strerror(rc));
			goto error;
		}
		tp->db=bdb;
	}
	
	/* set the journaling flags; flags indicate which operations
	   need to be journalled. (e.g possible to only journal INSERT.)
	*/
	rc = load_metadata_logflags(tp);
	if(rc!=0)
		INFO("No METADATA_LOGFLAGS in table: %s.\n", tblname);
	
	if ((tp->logflags & JLOG_FILE) == JLOG_FILE)
		bdblib_create_journal(_db, tp);
	
	return tp;
	
error:
	if(tp) 
	{
		pkg_free(tp->name.s);
		pkg_free(tp);
	}
	return NULL;
}
示例#7
0
int
main(int argc, char *argv[])
{
    /* Initialize our handles */
    DB *dbp = NULL;
    DB_ENV *envp = NULL;

    thread_t writer_threads[NUMWRITERS];
    int ch, i, ret, ret_t;
    u_int32_t env_flags;
    char *db_home_dir;
    /* Application name */
    const char *prog_name = "txn_guide";
    /* Database file name */
    const char *file_name = "mydb.db";

    /* Parse the command line arguments */
#ifdef _WIN32
    db_home_dir = ".\\";
#else
    db_home_dir = "./";
#endif
    while ((ch = getopt(argc, argv, "h:")) != EOF)
	switch (ch) {
	case 'h':
	    db_home_dir = optarg;
	    break;
	case '?':
	default:
	    return (usage());
	}

    /* Create the environment */
    ret = db_env_create(&envp, 0);
    if (ret != 0) {
	fprintf(stderr, "Error creating environment handle: %s\n",
	    db_strerror(ret));
	goto err;
    }

     /*
     * Indicate that we want db to perform lock detection internally.
     * Also indicate that the transaction with the fewest number of
     * write locks will receive the deadlock notification in
     * the event of a deadlock.
     */
    ret = envp->set_lk_detect(envp, DB_LOCK_MINWRITE);
    if (ret != 0) {
	fprintf(stderr, "Error setting lock detect: %s\n",
	    db_strerror(ret));
	goto err;
    }

    env_flags =
      DB_CREATE     |  /* Create the environment if it does not exist */
      DB_RECOVER    |  /* Run normal recovery. */
      DB_INIT_LOCK  |  /* Initialize the locking subsystem */
      DB_INIT_LOG   |  /* Initialize the logging subsystem */
      DB_INIT_TXN   |  /* Initialize the transactional subsystem. This
			* also turns on logging. */
      DB_INIT_MPOOL |  /* Initialize the memory pool (in-memory cache) */
      DB_THREAD;       /* Cause the environment to be free-threaded */

    /* Now actually open the environment */
    ret = envp->open(envp, db_home_dir, env_flags, 0);
    if (ret != 0) {
	fprintf(stderr, "Error opening environment: %s\n",
	    db_strerror(ret));
	goto err;
    }

    /*
     * If we had utility threads (for running checkpoints or
     * deadlock detection, for example) we would spawn those
     * here. However, for a simple example such as this,
     * that is not required.
     */

    /* Open the database */
    ret = open_db(&dbp, prog_name, file_name,
      envp, DB_DUPSORT);
    if (ret != 0)
	goto err;

    /* Initialize a mutex. Used to help provide thread ids. */
    (void)mutex_init(&thread_num_lock, NULL);

    /* Start the writer threads. */
    for (i = 0; i < NUMWRITERS; i++)
	(void)thread_create(
	   &writer_threads[i], NULL, writer_thread, (void *)dbp);

    /* Join the writers */
    for (i = 0; i < NUMWRITERS; i++)
	(void)thread_join(writer_threads[i], NULL);

err:
    /* Close our database handle, if it was opened. */
    if (dbp != NULL) {
	ret_t = dbp->close(dbp, 0);
	if (ret_t != 0) {
	    fprintf(stderr, "%s database close failed: %s\n",
		file_name, db_strerror(ret_t));
	    ret = ret_t;
	}
    }

    /* Close our environment, if it was opened. */
    if (envp != NULL) {
	ret_t = envp->close(envp, 0);
	if (ret_t != 0) {
	    fprintf(stderr, "environment close failed: %s\n",
		db_strerror(ret_t));
		ret = ret_t;
	}
    }

    /* Final status message and return. */
    printf("I'm all done.\n");
    return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
示例#8
0
文件: simple_txn.c 项目: kanbang/Colt
int
doloop(DB_ENV *dbenv)
{
    DB *dbp;
    DBT key, data;
    char buf[BUFSIZE], *rbuf;
    int ret;
    u_int32_t db_flags;

    dbp = NULL;
    memset(&key, 0, sizeof(key));
    memset(&data, 0, sizeof(data));
    ret = 0;

    for (;;) {
	if (dbp == NULL) {
	    if ((ret = db_create(&dbp, dbenv, 0)) != 0)
		return (ret);

	    db_flags = DB_AUTO_COMMIT | DB_CREATE;

	    if ((ret = dbp->open(dbp,
		NULL, DATABASE, NULL, DB_BTREE, db_flags, 0)) != 0) {
		dbenv->err(dbenv, ret, "DB->open");
		goto err;
	    }
	}

	printf("QUOTESERVER> ");
	fflush(stdout);

	if (fgets(buf, sizeof(buf), stdin) == NULL)
	    break;
	if (strtok(&buf[0], " \t\n") == NULL) {
	    switch ((ret = print_stocks(dbp))) {
	    case 0:
		continue;
	    default:
		dbp->err(dbp, ret, "Error traversing data");
		goto err;
	    }
	}
	rbuf = strtok(NULL, " \t\n");
	if (rbuf == NULL || rbuf[0] == '\0') {
	    if (strncmp(buf, "exit", 4) == 0 ||
		strncmp(buf, "quit", 4) == 0)
		break;
	    dbenv->errx(dbenv, "Format: TICKER VALUE");
	    continue;
	}

	key.data = buf;
	key.size = (u_int32_t)strlen(buf);

	data.data = rbuf;
	data.size = (u_int32_t)strlen(rbuf);

	if ((ret = dbp->put(dbp, NULL, &key, &data, 0)) != 0)
	{
	    dbp->err(dbp, ret, "DB->put");
	    if (ret != DB_KEYEXIST)
		goto err;
	}
    }
err: if (dbp != NULL)
	(void)dbp->close(dbp, DB_NOSYNC);

    return (ret);
}
示例#9
0
文件: backup.c 项目: galaxyeye/bdb
/* Close or free all handles and commit or rollback the transaction. */
static int backupCleanup(sqlite3_backup *p)
{
	int rc, rc2, ret;
	void *app;
	DB *db;

	rc = rc2 = SQLITE_OK;

	if (!p || p->rc == SQLITE_OK)
		return rc;

	rc2 = sqlite3BtreeCloseCursor(&p->destCur);
	if (rc2 != SQLITE_OK)
		rc = rc2;
	if (p->srcCur) {
		db = p->srcCur->dbp;
		app = db->app_private;
		if ((ret = p->srcCur->close(p->srcCur)) == 0)
			ret = db->close(db, DB_NOSYNC);
		rc2 = dberr2sqlite(ret);
		/*
		 * The KeyInfo was allocated in btreeSetupIndex,
		 * so have to deallocate it here.
		 */
		if (app)
			sqlite3DbFree(p->pSrcDb, app);
	}
	if (rc2 != SQLITE_OK)
		rc = rc2;
	p->srcCur = 0;

	/*
	 * May retry on a locked or busy error, so keep
	 * these values.
	 */
	if (p->rc != SQLITE_LOCKED && p->rc != SQLITE_BUSY) {
		if (p->srcName)
			sqlite3_free(p->srcName);
		if (p->destName != 0)
			sqlite3_free(p->destName);
		p->srcName = p->destName = NULL;
	}

	if (p->tables != 0)
			sqlite3_free(p->tables);
	p->tables = NULL;

	if (p->pSrc->nBackup)
		p->pSrc->nBackup--;
	if (p->pDest != NULL && p->pDest->nBackup)
		p->pDest->nBackup--;
	if (p->srcTxn) {
		if (p->rc == SQLITE_DONE)
			ret = p->srcTxn->commit(p->srcTxn, 0);
		else
			ret = p->srcTxn->abort(p->srcTxn);
		rc2 = dberr2sqlite(ret);
	}
	p->srcTxn = 0;
	if (rc2 != SQLITE_OK && sqlite3BtreeIsInTrans(p->pDest)) {
		rc = rc2;
		if (p->rc == SQLITE_DONE)
			rc2 = sqlite3BtreeCommit(p->pDest);
		else
			rc2 = sqlite3BtreeRollback(p->pDest);
		if (rc2 != SQLITE_OK)
			rc = rc2;
	}

	if (p->pDest && p->openDest) {
		char path[512];

		/*
		 * If successfully done then delete the old backup, if
		 * an error then delete the current database and restore
		 * the old backup.
		 */
		sqlite3_snprintf(sizeof(path), path,
		    "%s%s", p->fullName, BACKUP_SUFFIX);
		if (p->rc == SQLITE_DONE) {
			rc2 = btreeDeleteEnvironment(p->pDest, path, 0);
		} else {
			rc2 = btreeDeleteEnvironment(p->pDest, p->fullName, 0);
			if (!__os_exists(NULL, path, 0))
				__os_rename(NULL, path, p->fullName, 0);
		}
		if (rc == SQLITE_OK)
			rc = rc2;
		if (rc == SQLITE_OK) {
			p->pDest = NULL;
			p->pDestDb->aDb[p->iDb].pBt = NULL;
			p->openDest = 0;
			rc = sqlite3BtreeOpen(p->fullName, p->pDestDb,
			    &p->pDest,
			    SQLITE_DEFAULT_CACHE_SIZE | SQLITE_OPEN_MAIN_DB,
			    p->pDestDb->openFlags);
			p->pDestDb->aDb[p->iDb].pBt = p->pDest;
			if (rc == SQLITE_OK) {
				p->pDestDb->aDb[p->iDb].pSchema =
				    sqlite3SchemaGet(p->pDestDb, p->pDest);
				if (!p->pDestDb->aDb[p->iDb].pSchema)
					p->rc = SQLITE_NOMEM;
			} else
				p->pDestDb->aDb[p->iDb].pSchema = NULL;
			if (rc == SQLITE_OK)
				p->pDest->pBt->db_oflags |= DB_CREATE;
			/*
			 * Have to delete the schema here on error to avoid
			 * assert failure.
			 */
			if (p->pDest == NULL &&
			    p->pDestDb->aDb[p->iDb].pSchema != NULL) {
				sqlite3SchemaClear(
				    p->pDestDb->aDb[p->iDb].pSchema);
				p->pDestDb->aDb[p->iDb].pSchema = NULL;
			}
#ifdef SQLITE_HAS_CODEC
			if (rc == SQLITE_OK) {
				if (p->iDb == 0)
					rc = sqlite3_key(p->pDestDb,
					    p->pSrc->pBt->encrypt_pwd,
					    p->pSrc->pBt->encrypt_pwd_len);
				else
					rc = sqlite3CodecAttach(p->pDestDb,
					    p->iDb, p->pSrc->pBt->encrypt_pwd,
					    p->pSrc->pBt->encrypt_pwd_len);
			}
#endif
		}
	}
	if (p->rc != SQLITE_LOCKED && p->rc != SQLITE_BUSY) {
		if (p->fullName != 0)
			sqlite3_free(p->fullName);
		p->fullName = NULL;
	}
	p->lastUpdate = p->pSrc->updateDuringBackup;
	return rc;
}
示例#10
0
static int remove_collection_entry(char* storage_space, char* collname)
{
    char collections_db[PATH_MAX];
    DB * dbp;
    DBT key, data;
    int ret = 0;
    TROVE_coll_id coll_id;

    sprintf(collections_db, "%s/collections.db", storage_space);

    ret = access(collections_db, F_OK);
    if(ret == -1 && errno == ENOENT)
    {
        fprintf(stderr, "Error: could not find %s.\n", collections_db);
        fprintf(stderr, "Error: src directory is not a known format.\n");
        return ret;
    }
    else if(ret == -1)
    {
        fprintf(stderr, "access(%s): %s\n", collections_db, strerror(errno));
        return -1;
    }

    ret = db_create(&dbp, NULL, 0);
    if(ret != 0)
    {
        fprintf(stderr, "Error: db_create: %s.\n", db_strerror(ret));
        return -1;
    }

    ret = dbp->open(dbp,
#ifdef HAVE_TXNID_PARAMETER_TO_DB_OPEN
                    NULL,
#endif
                    collections_db,
                    NULL,
                    DB_UNKNOWN,
                    0,
                    0);
    if(ret != 0)
    {
        fprintf(stderr, "Error: dbp->open: %s.\n", db_strerror(ret));
        return(-1);
    }

    memset(&key, 0, sizeof(key));
    memset(&data, 0, sizeof(data));

    key.data = collname;
    key.size = strlen(collname) + 1;
    data.data = &coll_id;
    data.ulen = sizeof(coll_id);
    data.flags = DB_DBT_USERMEM;

    ret = dbp->get(dbp, NULL, &key, &data, 0);
    if (ret != 0)
    {
        fprintf(stderr, "Error: dbp->get: %s\n", db_strerror(ret));
        return -1;
    }

    ret = dbp->del(dbp, NULL, &key, 0);
    if (ret != 0)
    {
        fprintf(stderr, "Error: dbp->del: %s\n", db_strerror(ret));
        return -1;
    }

    ret = dbp->sync(dbp, 0);
    if (ret != 0)
    {
        fprintf(stderr, "Error: dbp->sync: %s\n", db_strerror(ret));
        return -1;
    }

    dbp->close(dbp, 0);
    return 0;
}
示例#11
0
/**
 * Migrates collection xattrs from a 0.0.1 DBPF collection
 * \return 0 on succes, -1 on failure
 */
static int translate_coll_eattr_0_0_1(
    char* old_coll_path,            /**< path to old trove collection */
    TROVE_coll_id coll_id,          /**< collection id in string format */
    char* coll_name,                /**< name of collection */
    TROVE_context_id trove_context) /**< open trove context */                
{
    int ret = -1;
    char coll_db[PATH_MAX];
    DB *dbp;
    DBT key, data;
    DBC *dbc_p = NULL;
    TROVE_keyval_s t_key;
    TROVE_keyval_s t_val;
    TROVE_op_id op_id;
    int count = 0;
    TROVE_ds_state state;

    sprintf(coll_db, "%s/collection_attributes.db", old_coll_path);
    ret = db_create(&dbp, NULL, 0);
    if(ret != 0)
    {
        fprintf(stderr, "Error: db_create: %s.\n", db_strerror(ret));
        return(-1);
    }
    
    /* open collection_attributes.db from old collection */
    ret = dbp->open(dbp,
#ifdef HAVE_TXNID_PARAMETER_TO_DB_OPEN
                    NULL,
#endif
                    coll_db,
                    NULL,
                    DB_UNKNOWN,
                    0,
                    0);
    if(ret != 0)
    {
        fprintf(stderr, "Error: dbp->open: %s.\n", db_strerror(ret));
        return(-1);
    }

    ret = dbp->cursor(dbp, NULL, &dbc_p, 0);
    if (ret != 0)
    {
        fprintf(stderr, "Error: dbp->cursor: %s.\n", db_strerror(ret));
        dbp->close(dbp, 0);
        return(-1);
    }

    memset(&key, 0, sizeof(key));
    key.data = malloc(DEF_KEY_SIZE);
    if(!key.data)
    {
        perror("malloc");    
        dbc_p->c_close(dbc_p);
        dbp->close(dbp, 0);
        return(-1);
    }
    key.size = key.ulen = DEF_KEY_SIZE;
    key.flags |= DB_DBT_USERMEM;

    memset(&data, 0, sizeof(data));
    data.data = malloc(DEF_DATA_SIZE);
    if(!data.data)
    {
        perror("malloc");    
        free(key.data);
        dbc_p->c_close(dbc_p);
        dbp->close(dbp, 0);
        return(-1);
    }
    data.size = data.ulen = DEF_DATA_SIZE;
    data.flags |= DB_DBT_USERMEM;

    do
    {
        /* iterate through eattr's on the old collection */
        ret = dbc_p->c_get(dbc_p, &key, &data, DB_NEXT);
        if (ret != DB_NOTFOUND && ret != 0)
        {
            fprintf(stderr, "Error: dbc_p->c_get: %s.\n", db_strerror(ret));
            free(data.data);
            free(key.data);
            dbc_p->c_close(dbc_p);
            dbp->close(dbp, 0);
            return(-1);
        }
        /* skip the version attribute- we don't want to copy that one */
        if(ret == 0 && strncmp(key.data, "trove-dbpf-version", 
                               strlen("trove-dbpf-version")) != 0)
        {
            if(verbose) printf("VERBOSE Migrating collection eattr: %s\n", (char*)key.data);

            memset(&t_key, 0, sizeof(t_key));
            memset(&t_val, 0, sizeof(t_val));
            t_key.buffer = key.data;
            t_key.buffer_sz = key.size;
            t_val.buffer = data.data;
            t_val.buffer_sz = data.size;

            /* write out new eattr's */
            state = 0;
            ret = trove_collection_seteattr(
                coll_id,
                &t_key,
                &t_val,
                0,
                NULL,
                trove_context,
                &op_id);
            while (ret == 0)
            {
                ret = trove_dspace_test(
                    coll_id, op_id, trove_context, &count, NULL, NULL,
                    &state, 10);
            }
            if ((ret < 0) || (ret == 1 && state != 0))
            {
                fprintf(stderr, "Error: trove_collection_seteattr failure.\n");
                free(data.data);
                free(key.data);
                dbc_p->c_close(dbc_p);
                dbp->close(dbp, 0);
                return -1; 
            }   
        }
    }while(ret != DB_NOTFOUND);

    free(data.data);
    free(key.data);
    dbc_p->c_close(dbc_p);
    dbp->close(dbp, 0);

    return(0);
}
示例#12
0
/**
 * Reads the version number from a 0.0.1 DBPF collection
 * \return 0 on succes, -1 on failure
 */
static int src_get_version_0_0_1(
    char* storage_space,   /**< path to storage space */
    TROVE_coll_id coll_id, /**< collection id */
    char* ver_string,      /**< version in string format */
    int ver_string_max)    /**< maximum size of version string */
{
    char coll_db[PATH_MAX];
    int ret;
    DB *dbp;
    DBT key, data;

    sprintf(coll_db, "%s/%08x/collection_attributes.db", 
            storage_space, coll_id);

    /* try to find a collections db */
    ret = access(coll_db, F_OK);
    if(ret == -1 && errno == ENOENT)
    {
        fprintf(stderr, "Error: could not find %s.\n", coll_db);
        fprintf(stderr, "Error: src directory is not a known format.\n");
        return(-1);
    }
    else if(ret == -1)
    {
        fprintf(stderr, "access(%s): %s\n", coll_db, strerror(errno));
        return(-1);
    }

    ret = db_create(&dbp, NULL, 0);
    if(ret != 0)
    {
        fprintf(stderr, "Error: db_create: %s.\n", db_strerror(ret));
        return(-1);
    }
    
    ret = dbp->open(dbp,
#ifdef HAVE_TXNID_PARAMETER_TO_DB_OPEN
                          NULL,
#endif
                          coll_db,
                          NULL,
                          DB_UNKNOWN,
                          0,
                          0);
    if(ret != 0)
    {
        fprintf(stderr, "Error: dbp->open: %s.\n", db_strerror(ret));
        return(-1);
    }

    memset(&key, 0, sizeof(key));
    memset(&data, 0, sizeof(data));
    key.data = "trove-dbpf-version";
    key.size = strlen("trove-dbpf-version");
    data.data = ver_string;
    data.size = data.ulen = ver_string_max;
    data.flags |= DB_DBT_USERMEM;

    ret = dbp->get(dbp, NULL, &key, &data, 0);
    if(ret != 0)
    {
        fprintf(stderr, "Error: dbp->get: %s\n", db_strerror(ret));
        return(-1);
    }

    dbp->close(dbp, 0);

    return(0);
}
示例#13
0
/**
 * Migrates a single keyval db from a 0.0.1 DBPF collection
 * \return 0 on succes, -1 on failure
 */
static int translate_keyval_db_0_0_1(
    TROVE_coll_id coll_id,          /**< collection id */
    char* full_db_path,             /**< fully resolved path to db file */
    TROVE_handle handle,            /**< handle of the object */
    char* coll_name,                /**< name of collection */
    TROVE_context_id trove_context) /**< open trove context */                
{
    int ret = -1;
    DB *dbp;
    DBT key, data;
    DBC *dbc_p = NULL;
    TROVE_op_id op_id;
    int count = 0;
    TROVE_ds_state state;
    TROVE_keyval_s t_key;
    TROVE_keyval_s t_val;

    if(verbose) 
        printf("VERBOSE Migrating keyvals for handle: %llu\n", llu(handle));

    ret = db_create(&dbp, NULL, 0);
    if(ret != 0)
    {
        fprintf(stderr, "Error: db_create: %s.\n", db_strerror(ret));
        return(-1);
    }
     
    ret = dbp->open(dbp,
#ifdef HAVE_TXNID_PARAMETER_TO_DB_OPEN
                    NULL,
#endif
                    full_db_path,
                    NULL,
                    DB_UNKNOWN,
                    0,
                    0);
    if(ret != 0)
    {
        fprintf(stderr, "Error: dbp->open: %s.\n", db_strerror(ret));
        return(-1);
    }

    ret = dbp->cursor(dbp, NULL, &dbc_p, 0);
    if (ret != 0)
    {
        fprintf(stderr, "Error: dbp->cursor: %s.\n", db_strerror(ret));
        dbp->close(dbp, 0);
        return(-1);
    }

    memset(&key, 0, sizeof(key));
    key.data = malloc(DEF_KEY_SIZE);
    if(!key.data)
    {
        perror("malloc");    
        dbc_p->c_close(dbc_p);
        dbp->close(dbp, 0);
        return(-1);
    }
    key.size = key.ulen = DEF_KEY_SIZE;
    key.flags |= DB_DBT_USERMEM;

    memset(&data, 0, sizeof(data));
    data.data = malloc(DEF_DATA_SIZE);
    if(!data.data)
    {
        perror("malloc");    
        free(key.data);
        dbc_p->c_close(dbc_p);
        dbp->close(dbp, 0);
        return(-1);
    }
    data.size = data.ulen = DEF_DATA_SIZE;
    data.flags |= DB_DBT_USERMEM;

    do
    {
        /* iterate through keys in the old keyval db */
        ret = dbc_p->c_get(dbc_p, &key, &data, DB_NEXT);
        if (ret != DB_NOTFOUND && ret != 0)
        {
            fprintf(stderr, "Error: dbc_p->c_get: %s.\n", db_strerror(ret));
            free(data.data);
            free(key.data);
            dbc_p->c_close(dbc_p);
            dbp->close(dbp, 0);
            return(-1);
        }
        if(ret == 0)
        {
            int tvalbuf_free = 0;
            PVFS_ds_flags trove_flags = TROVE_SYNC;
            memset(&t_key, 0, sizeof(t_key));
            memset(&t_val, 0, sizeof(t_val));
            if(translate_keyval_key_0_0_1(&t_key, &key) < 0)
            {
                /* assume its a component name of a directory entry */
                t_key.buffer = key.data;
                t_key.buffer_sz = key.size;
		t_val.buffer = data.data;
		t_val.buffer_sz = data.size;
                trove_flags |= TROVE_KEYVAL_HANDLE_COUNT;
                trove_flags |= TROVE_NOOVERWRITE;
            }
            else if(!strncmp(t_key.buffer, "md", 2)) /* metafile_dist */
            {
                PINT_dist *newdist;
                newdist = data.data;
                
                ret = translate_dist_0_0_1(newdist);
                if(ret != 0)
                {
                    free(data.data);
                    free(key.data);
                    dbc_p->c_close(dbc_p);
                    dbp->close(dbp, 0);
                    return(-1);
                }
                
                t_val.buffer_sz = PINT_DIST_PACK_SIZE(newdist);
                t_val.buffer = malloc(t_val.buffer_sz);
                if(!t_val.buffer)
                {
                    fprintf(stderr, "Error: trove_keyval_write failure.\n");
                    free(data.data);
                    free(key.data);
                    dbc_p->c_close(dbc_p);
                    dbp->close(dbp, 0);
                    return -1; 
                }
                tvalbuf_free = 1;

                PINT_dist_encode(t_val.buffer, newdist);
            } 
            else
            {
                t_val.buffer = data.data;
                t_val.buffer_sz = data.size;
            }
           
            /* write out new keyval pair */
            state = 0;
            ret = trove_keyval_write(
                coll_id, handle, &t_key, &t_val, trove_flags, 0, NULL,
                trove_context, &op_id, NULL);

            while (ret == 0)
            {   
                ret = trove_dspace_test(
                    coll_id, op_id, trove_context, &count, NULL, NULL,
                    &state, 10);
            }
            
            if(tvalbuf_free)
            {
                tvalbuf_free = 0;
                free(t_val.buffer);
            }

            if ((ret < 0) || (ret == 1 && state != 0))
            {
                fprintf(stderr, "Error: trove_keyval_write failure.\n");
                free(data.data);
                free(key.data);
                dbc_p->c_close(dbc_p);
                dbp->close(dbp, 0);
                return -1; 
            }
        }
    }while(ret != DB_NOTFOUND);

    free(data.data);
    free(key.data);
    dbc_p->c_close(dbc_p);
    dbp->close(dbp, 0);

    return(0);
}
示例#14
0
/**
 * Migrates dspace attrs from a 0.0.1 DBPF collection
 * \return 0 on succes, -1 on failure
 */
static int translate_dspace_attr_0_0_1(
    char* old_coll_path,            /**< path to old collection */
    TROVE_coll_id coll_id,          /**< collection id */
    char* coll_name,                /**< name of collection */
    TROVE_context_id trove_context) /**< open trove context */                
{
    int ret = -1;
    char attr_db[PATH_MAX];
    DB *dbp;
    DBT key, data;
    DBC *dbc_p = NULL;
    TROVE_op_id op_id;
    int count = 0;
    TROVE_ds_state state;
    TROVE_handle_extent cur_extent;
    TROVE_handle_extent_array extent_array;
    TROVE_handle new_handle;
    TROVE_handle* tmp_handle;
    PVFS_ds_storedattr_0_0_1* tmp_attr;
    TROVE_ds_attributes new_attr;

    sprintf(attr_db, "%s/dataspace_attributes.db", old_coll_path);
    ret = db_create(&dbp, NULL, 0);
    if(ret != 0)
    {
        fprintf(stderr, "Error: db_create: %s.\n", db_strerror(ret));
        return(-1);
    }
    
    /* open dataspace_attributes.db from old collection */
    ret = dbp->open(dbp,
#ifdef HAVE_TXNID_PARAMETER_TO_DB_OPEN
                    NULL,
#endif
                    attr_db,
                    NULL,
                    DB_UNKNOWN,
                    0,
                    0);
    if(ret != 0)
    {
        fprintf(stderr, "Error: dbp->open: %s.\n", db_strerror(ret));
        return(-1);
    }

    ret = dbp->cursor(dbp, NULL, &dbc_p, 0);
    if (ret != 0)
    {
        fprintf(stderr, "Error: dbp->cursor: %s.\n", db_strerror(ret));
        dbp->close(dbp, 0);
        return(-1);
    }

    memset(&key, 0, sizeof(key));
    key.data = malloc(DEF_KEY_SIZE);
    if(!key.data)
    {
        perror("malloc");    
        dbc_p->c_close(dbc_p);
        dbp->close(dbp, 0);
        return(-1);
    }
    key.size = key.ulen = DEF_KEY_SIZE;
    key.flags |= DB_DBT_USERMEM;

    memset(&data, 0, sizeof(data));
    data.data = malloc(DEF_DATA_SIZE);
    if(!data.data)
    {
        perror("malloc");    
        free(key.data);
        dbc_p->c_close(dbc_p);
        dbp->close(dbp, 0);
        return(-1);
    }
    data.size = data.ulen = DEF_DATA_SIZE;
    data.flags |= DB_DBT_USERMEM;

    do
    {
        /* iterate through handles in the old collection */
        ret = dbc_p->c_get(dbc_p, &key, &data, DB_NEXT);
        if (ret != DB_NOTFOUND && ret != 0)
        {
            fprintf(stderr, "Error: dbc_p->c_get: %s.\n", db_strerror(ret));
            free(data.data);
            free(key.data);
            dbc_p->c_close(dbc_p);
            dbp->close(dbp, 0);
            return(-1);
        }
        if(ret == 0)
        {
            tmp_handle = ((PVFS_handle*)key.data);
            tmp_attr = ((PVFS_ds_storedattr_0_0_1*)data.data);

            if(verbose) printf("VERBOSE Migrating attributes for handle: %llu, type: %d\n", 
                llu(*tmp_handle), (int)tmp_attr->type);

            cur_extent.first = cur_extent.last = *tmp_handle;
            extent_array.extent_count = 1;
            extent_array.extent_array = &cur_extent;

            state = 0;
            ret = trove_dspace_create(
                coll_id, &extent_array, &new_handle,
                tmp_attr->type, NULL,
                (TROVE_SYNC | TROVE_FORCE_REQUESTED_HANDLE),
                NULL, trove_context, &op_id, NULL);

            while (ret == 0)
            {
                ret = trove_dspace_test(coll_id, op_id, trove_context,
                                        &count, NULL, NULL, &state,
                                        10);
            }
            if ((ret < 0) || (ret == 1 && state != 0))
            {
                fprintf(stderr, "Error: trove_dspace_create failure.\n");
                free(data.data);
                free(key.data);
                dbc_p->c_close(dbc_p);
                dbp->close(dbp, 0);
                return -1; 
            }
            
            /* convert out of stored format, disregard k_size and b_size
             * (those will be implicitly set later) 
             */
            /* NOTE: we cannot memcpy or use trove_ds_stored_to_attr() macro
             * because the alignment changed after 0.0.1
             */
            new_attr.fs_id = tmp_attr->fs_id;
            new_attr.handle = tmp_attr->handle;
            new_attr.type = tmp_attr->type;
            new_attr.uid = tmp_attr->uid;
            new_attr.gid = tmp_attr->gid;
            new_attr.mode = tmp_attr->mode;
            new_attr.ctime = tmp_attr->ctime;
            new_attr.mtime = tmp_attr->mtime;
            new_attr.atime = tmp_attr->atime;
            new_attr.u.metafile.dfile_count = tmp_attr->dfile_count;
            new_attr.u.metafile.dist_size = tmp_attr->dist_size;
            
            /* write the attributes into the new collection */
            state = 0;
            ret = trove_dspace_setattr(coll_id,
                                       *tmp_handle,
                                       &new_attr,
                                       TROVE_SYNC,
                                       NULL,
                                       trove_context,
                                       &op_id, NULL);
            while (ret == 0)
            {
                ret = trove_dspace_test( 
                    coll_id, op_id, trove_context, &count, NULL, NULL,
                    &state, 10);
            }
            if ((ret < 0) || (ret == 1 && state != 0))
            {
                fprintf(stderr, "Error: trove_dspace_setattr failure.\n");
                free(data.data);
                free(key.data);
                dbc_p->c_close(dbc_p);
                dbp->close(dbp, 0);
                return -1;
            }          
        }
    }while(ret != DB_NOTFOUND);

    free(data.data);
    free(key.data);
    dbc_p->c_close(dbc_p);
    dbp->close(dbp, 0);

    return(0);
}
示例#15
0
int
b_curwalk(int argc, char *argv[])
{
	extern char *optarg;
	extern int optind, __db_getopt_reset;
	DB *dbp;
	DBTYPE type;
	DBC *dbc;
	DBT key, data;
	db_recno_t recno;
	u_int32_t cachesize, pagesize, walkflags;
	int ch, i, count, dupcount, j;
	int prev, ret, skipdupwalk, sorted, walkcount;
	char *ts, dbuf[32], kbuf[32];

	type = DB_BTREE;
	cachesize = 10 * MEGABYTE;
	pagesize = 16 * 1024;
	count = 100000;
	dupcount = prev = skipdupwalk = sorted = 0;
	walkcount = 1000;
	ts = "Btree";
	__db_getopt_reset = 1;
	while ((ch = getopt(argc, argv, "C:c:d:P:pSst:w:")) != EOF)
		switch (ch) {
		case 'C':
			cachesize = (u_int32_t)atoi(optarg);
			break;
		case 'c':
			count = atoi(optarg);
			break;
		case 'd':
			dupcount = atoi(optarg);
			break;
		case 'P':
			pagesize = (u_int32_t)atoi(optarg);
			break;
		case 'p':
			prev = 1;
			break;
		case 'S':
			skipdupwalk = 1;
			break;
		case 's':
			sorted = 1;
			break;
		case 't':
			switch (optarg[0]) {
			case 'B': case 'b':
				ts = "Btree";
				type = DB_BTREE;
				break;
			case 'H': case 'h':
				if (b_util_have_hash())
					return (0);
				ts = "Hash";
				type = DB_HASH;
				break;
			case 'Q': case 'q':
				if (b_util_have_queue())
					return (0);
				ts = "Queue";
				type = DB_QUEUE;
				break;
			case 'R': case 'r':
				ts = "Recno";
				type = DB_RECNO;
				break;
			default:
				return (b_curwalk_usage());
			}
			break;
		case 'w':
			walkcount = atoi(optarg);
			break;
		case '?':
		default:
			return (b_curwalk_usage());
		}
	argc -= optind;
	argv += optind;
	if (argc != 0)
		return (b_curwalk_usage());

	/*
	 * Queue and Recno don't support duplicates.
	 */
	if (dupcount != 0 && (type == DB_QUEUE || type == DB_RECNO)) {
		fprintf(stderr,
		    "b_curwalk: Queue and Recno don't support duplicates\n");
		return (b_curwalk_usage());
	}

#if DB_VERSION_MAJOR < 3 || DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0
#define	DB_PREV_NODUP	0
	/*
	 * DB_PREV_NODUP wasn't available until after 3.0.55.
	 *
	 * For some reason, testing sorted duplicates doesn't work either.
	 * I don't really care about 3.0.55 any more, just ignore it.
	 */
	return (0);
#endif
	/* Create the database. */
	DB_BENCH_ASSERT(db_create(&dbp, NULL, 0) == 0);
	DB_BENCH_ASSERT(dbp->set_cachesize(dbp, 0, cachesize, 0) == 0);
	DB_BENCH_ASSERT(dbp->set_pagesize(dbp, pagesize) == 0);
	dbp->set_errfile(dbp, stderr);

	/* Set record length for Queue. */
	if (type == DB_QUEUE)
		DB_BENCH_ASSERT(dbp->set_re_len(dbp, 20) == 0);

	/* Set duplicates flag. */
	if (dupcount != 0)
		DB_BENCH_ASSERT(
		    dbp->set_flags(dbp, sorted ? DB_DUPSORT : DB_DUP) == 0);

#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1
	DB_BENCH_ASSERT(dbp->open(
	    dbp, NULL, TESTFILE, NULL, type, DB_CREATE, 0666) == 0);
#else
	DB_BENCH_ASSERT(dbp->open(
	    dbp, TESTFILE, NULL, type, DB_CREATE, 0666) == 0);
#endif

	/* Initialize the data. */
	memset(&key, 0, sizeof(key));
	memset(&data, 0, sizeof(data));

	/* Insert count in-order key/data pairs. */
	data.data = dbuf;
	data.size = 20;
	if (type == DB_BTREE || type == DB_HASH) {
		key.size = 10;
		key.data = kbuf;
		for (i = 0; i < count; ++i) {
			(void)snprintf(kbuf, sizeof(kbuf), "%010d", i);
			for (j = 0; j <= dupcount; ++j) {
				(void)snprintf(dbuf, sizeof(dbuf), "%020d", j);
				DB_BENCH_ASSERT(
				    dbp->put(dbp, NULL, &key, &data, 0) == 0);
			}
		}
	} else {
		key.data = &recno;
		key.size = sizeof(recno);
		for (i = 0, recno = 1; i < count; ++i, ++recno)
			DB_BENCH_ASSERT(
			    dbp->put(dbp, NULL, &key, &data, 0) == 0);
	}

	walkflags = prev ?
	    (skipdupwalk ? DB_PREV_NODUP : DB_PREV) :
	    (skipdupwalk ? DB_NEXT_NODUP : DB_NEXT);

	/* Walk the cursor through the tree N times. */
	TIMER_START;
	for (i = 0; i < walkcount; ++i) {
		DB_BENCH_ASSERT(dbp->cursor(dbp, NULL, &dbc, 0) == 0);
		while ((ret = dbc->c_get(dbc, &key, &data, walkflags)) == 0)
			;
		DB_BENCH_ASSERT(ret == DB_NOTFOUND);
		DB_BENCH_ASSERT(dbc->c_close(dbc) == 0);
	}
	TIMER_STOP;

	printf("# %d %s %s cursor of %d 10/20 byte key/data items",
	    walkcount, ts, prev ?
	    (skipdupwalk ? "DB_PREV_NODUP" : "DB_PREV") :
	    (skipdupwalk ? "DB_NEXT_NODUP" : "DB_NEXT"),
	    count);
	if (dupcount != 0)
		printf(" with %d dups", dupcount);
	printf("\n");

	/*
	 * An "operation" is traversal of a single key/data pair -- not a
	 * return of the key/data pair, since some versions of this test
	 * skip duplicate key/data pairs.
	 *
	 * Use a "double" so we don't overflow.
	 */
	TIMER_DISPLAY((double)count * walkcount);

	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0);

	return (EXIT_SUCCESS);
}
示例#16
0
文件: backup.c 项目: galaxyeye/bdb
/*
 * Use Bulk Get/Put to copy the given number of pages worth of
 * records from the source database to the destination database,
 * this function should be called until all tables are copied, at
 * which point it will return SQLITE_DONE.  Both Btrees need to
 * have transactions before calling this function.
 * p->pSrc - Source Btree
 * p->tables - Contains a list of iTables to copy, gotten using
 *          btreeGetTables().
 * p->currentTable - Index in tables of the current table being copied.
 * p->srcCur -  Cursor on the current source table being copied.
 * p->pDest - Destiniation Btree.
 * p->destCur - BtCursor on the destination table being copied into.
 * pages - Number of pages worth of data to copy.
 */
static int btreeCopyPages(sqlite3_backup *p, int *pages)
{
	DB *dbp;
	DBT dataOut, dataIn;
	char bufOut[MULTI_BUFSIZE], bufIn[MULTI_BUFSIZE];
	int ret, rc, copied, srcIsDupIndex;
	void *in, *out, *app;

	ret = 0;
	rc = SQLITE_OK;
	dbp = NULL;
	copied = 0;
	memset(&dataOut, 0, sizeof(dataOut));
	memset(&dataIn, 0, sizeof(dataIn));
	dataOut.flags = DB_DBT_USERMEM;
	dataIn.flags = DB_DBT_USERMEM;
	dataOut.data = bufOut;
	dataOut.ulen = sizeof(bufOut);
	dataIn.data = bufIn;
	dataIn.ulen = sizeof(bufIn);

	while (*pages < 0 || *pages > copied) {
		/* No tables left to copy */
		if (p->tables[p->currentTable] == -1) {
			u32 val;
			/*
			 * Update the schema file format and largest rootpage
			 * in the meta data.  Other meta data values should
			 * not be changed.
			 */
			sqlite3BtreeGetMeta(p->pSrc, 1, &val);
			if (p->pSrc->db->errCode == SQLITE_BUSY) {
				rc = SQLITE_BUSY;
				goto err;
			}
			rc = sqlite3BtreeUpdateMeta(p->pDest, 1, val);
			if (rc != SQLITE_OK)
				goto err;
			sqlite3BtreeGetMeta(p->pSrc, 3, &val);
		       if (p->pSrc->db->errCode == SQLITE_BUSY) {
				rc = SQLITE_BUSY;
				goto err;
			}
			rc = sqlite3BtreeUpdateMeta(p->pDest, 3, val);
			if (rc != SQLITE_OK)
				goto err;
			ret = SQLITE_DONE;
			goto err;
		}
		/* If not currently copying a table, get the next table. */
		if (!p->srcCur) {
			rc = btreeGetUserTable(p->pSrc, p->srcTxn, &dbp,
			    p->tables[p->currentTable]);
			if (rc != SQLITE_OK)
				goto err;
			assert(dbp);
			memset(&p->destCur, 0, sizeof(p->destCur));
			/*
			 * Open a cursor on the destination table, this will
			 * create the table and allow the Btree to manage the
			 * DB object.
			 */
			sqlite3BtreeCursor(p->pDest, p->tables[p->currentTable],
			    1, dbp->app_private, &p->destCur);
			if ((rc = p->destCur.error) != SQLITE_OK) {
				app = dbp->app_private;
				dbp->close(dbp, DB_NOSYNC);
				if (app)
					sqlite3DbFree(p->pSrcDb, app);
				goto err;
			}
			/* Open a cursor on the source table. */
			if ((ret = dbp->cursor(dbp,
			    p->srcTxn, &p->srcCur, 0)) != 0)
				goto err;
			dbp = 0;
		}
		srcIsDupIndex = isDupIndex((p->tables[p->currentTable] & 1) ?
		    BTREE_INTKEY : 0, p->pSrc->pBt->dbStorage,
		    p->srcCur->dbp->app_private, p->srcCur->dbp);
		/*
		 * Copy the current table until the given number of
		 * pages is copied, or the entire table has been copied.
		 */
		while (*pages < 0 || *pages > copied) {
			DBT key, data;
			memset(&key, 0, sizeof(key));
			memset(&data, 0, sizeof(data));
			/* Do a Bulk Get from the source table. */
			ret = p->srcCur->get(p->srcCur, &key, &dataOut,
			    DB_NEXT | DB_MULTIPLE_KEY);
			if (ret == DB_NOTFOUND)
				break;
			if (ret != 0)
				goto err;
			/* Copy the records into the Bulk buffer. */
			DB_MULTIPLE_INIT(out, &dataOut);
			DB_MULTIPLE_WRITE_INIT(in, &dataIn);
			DB_MULTIPLE_KEY_NEXT(out, &dataOut, key.data,
			    key.size, data.data, data.size);
			while (out) {
				/*
				 * Have to translate the index formats if they
				 * are not the same.
				 */
				if (p->destCur.isDupIndex != srcIsDupIndex) {
					if (srcIsDupIndex) {
						p->destCur.key = key;
						p->destCur.data = data;
						if (!btreeCreateIndexKey(
						    &p->destCur)) {
							rc = SQLITE_NOMEM;
							goto err;
						}
						DB_MULTIPLE_KEY_WRITE_NEXT(in,
						    &dataIn,
						    p->destCur.index.data,
						    p->destCur.index.size,
						    p->destCur.data.data, 0);
					} else {
						/* Copy the key into the cursor
						 * index since spliting the key
						 * requires changing the
						 * internal memory.
						 */
						if (!allocateCursorIndex(
						    &p->destCur, key.size)) {
							rc = SQLITE_NOMEM;
							goto err;
						}
						memcpy(p->destCur.index.data,
						    key.data, key.size);
						p->destCur.index.size =
						    key.size;
						p->destCur.key.data =
						    p->destCur.index.data;
						p->destCur.key.size =
						    p->destCur.index.size;
						splitIndexKey(&p->destCur);
						DB_MULTIPLE_KEY_WRITE_NEXT(
						    in, &dataIn,
						    p->destCur.key.data,
						    p->destCur.key.size,
						    p->destCur.data.data,
						    p->destCur.data.size);
					}
				} else
					DB_MULTIPLE_KEY_WRITE_NEXT(in, &dataIn,
					    key.data, key.size,
					    data.data, data.size);
				DB_MULTIPLE_KEY_NEXT(out, &dataOut,
				    key.data, key.size,
				    data.data, data.size);
			}
			/* Insert into the destination table. */
			dbp = p->destCur.cached_db->dbp;
			if ((ret = dbp->put(dbp, p->pDest->savepoint_txn,
			    &dataIn, 0, DB_MULTIPLE_KEY)) != 0)
				goto err;
			dbp = NULL;
			copied += MULTI_BUFSIZE/SQLITE_DEFAULT_PAGE_SIZE;
		}
		/*
		 * Done copying the current table, time to look for a new
		 * table to copy.
		 */
		if (ret == DB_NOTFOUND) {
			ret = 0;
			rc = sqlite3BtreeCloseCursor(&p->destCur);
			if (p->srcCur) {
				app = p->srcCur->dbp->app_private;
				dbp = p->srcCur->dbp;
				p->srcCur->close(p->srcCur);
				ret = dbp->close(dbp, DB_NOSYNC);
				if (app)
					sqlite3DbFree(p->pSrcDb, app);
			}
			p->srcCur = NULL;
			if (ret != 0 || rc != SQLITE_OK)
				goto err;
			p->currentTable += 1;
		}
	}
	goto done;
err:	if (ret == SQLITE_DONE)
		return ret;
done:	return MAP_ERR(rc, ret);
}
示例#17
0
/**1 output_file = new file()
  2 dict =  new hash()
  3 while (free memory available)
  4 do token = next_token()
  5     if token not in dict
  6  	   postinglist = addtodict(dict, token)
  7     else postinglist = getpostinglist(dict, token)
  8     if full(postinglist)
  9   	   postinglist = doublepostinglist(dict, token)
  10    addtopostinglist(postinglist, docid(token))
  11 sorted_terms = sortterm(dict)	// for merge purpose 
 *12 writeblock(sorted_terms, dict, output_file)
 */
int
build_board_index(char *bname)
{
	char *word;
	char dirfile[PATH_MAX], docid2path[PATH_MAX], indexfile[PATH_MAX];
	char filepath[PATH_MAX]; /* article file path */
	char filename[20];
	char cachedir[PATH_MAX];
	char cachefile[PATH_MAX];
	char ndocsfile[PATH_MAX];
	DB *dbp;
	DBT key, data;
	int ret;
	int result = -1;
	FILE *filelist, *fp;
	struct postinglist *p;
	unsigned int docid = 1;
	gzFile cachefp;
	int gzerr;

	
	setboardfile(dirfile, bname, bname);
	set_brddocid2path_file(docid2path, bname);
	set_brdindex_file(indexfile, bname);

	/* Initialize the  DB structure.*/
	ret = db_create(&dbp, NULL, 0);
	if (ret != 0) {
		ERROR("create db hanldle failed");
		goto RETURN;
	}

	if (dbopen(dbp, docid2path, 1) != 0) {
		ERROR1("open db %s failed", docid2path);
		goto RETURN;		
	}
		
	if (!(filelist = fopen(dirfile, "r"))) {
		ERROR1("open file %s failed", dirfile);
		goto CLEAN_DB;
	}
	
	size_t size = 300000;	/* TODO: define this constant */
	struct dict_t **bucket = new_postinglist_bucket(size);
	if (bucket == NULL) {
		ERROR1("new_dict size=%u failed", size);
		goto CLEAN_FP;
	}

	g_text = malloc(MAX_FILE_SIZE);
	if (g_text == NULL) {
		ERROR("malloc failed");
		goto CLEAN_MEM;
	}

	/* Zero out the DBTs before using them. */
	memset(&key, 0, sizeof(DBT));
	memset(&data, 0, sizeof(DBT));
	
	key.size = sizeof(unsigned int);
	key.data = &docid;
	
	/* ensure the cache directory exists */
	setcachepath(cachedir, bname);
	f_mkdir(cachedir, 0755);

	while (fgets(filename, sizeof(filename), filelist)) {
		filename[strlen(filename) - 1] = '\0';
	
		data.size = strlen(filename) + 1;
		data.data = filename;
		
		setboardfile(filepath, bname, filename);
		ansi_filter(filepath);
		
		if (g_len != 0) {
			fprintf(stderr, "%d indexing %s\n", docid, filename);
			/* save to cache file */
			setcachefile(cachefile, bname, filename);
			cachefp = gzopen(cachefile, "wb");
			if (cachefp != NULL) {
				if (gzwrite(cachefp, g_text, g_len) != g_len) 
					ERROR(gzerror(cachefp, &gzerr));
				gzclose(cachefp);
			}
			
			g_pos = 0;
			while ((word = next_token())) {
				//DEBUG1("%s", word);
				p = get_postinglist(bucket, size, word);
				if (p->freq == p->size) /* is full */
					double_postinglist(p);
				addto_postinglist(p, docid);
			}
			
			/* write_docid2path */
			dbp->put(dbp, NULL, &key, &data, 0);
			docid++;
		}
	}

	write_index_file(bucket, size, indexfile);
	calc_doc_weight(bname, BOARD, docid - 1);
	set_brdndocs_file(ndocsfile, bname);
	fp = fopen(ndocsfile, "w");
	if (fp == NULL) {
		ERROR1("fopen %s failed", ndocsfile);
		goto CLEAN;
	}
	fprintf(fp, "%u", docid - 1);
	fclose(fp);

	/* it's ok */
	result = 0;
CLEAN:	
	free(g_text);	
CLEAN_MEM:
	free(bucket);
CLEAN_FP:
	fclose(filelist);	
CLEAN_DB:
	if (dbp != NULL)
		dbp->close(dbp, 0);
RETURN:
	return result;
}
示例#18
0
int
b_get(int argc, char *argv[])
{
	extern char *optarg;
	extern int optind;
	DB *dbp;
	DBTYPE type;
	DBT key, data;
	db_recno_t recno;
	u_int32_t cachesize;
	int ch, i, count;
	char *ts;

	type = DB_BTREE;
	cachesize = MEGABYTE;
	count = 100000;
	ts = "Btree";
	while ((ch = getopt(argc, argv, "C:c:t:")) != EOF)
		switch (ch) {
		case 'C':
			cachesize = (u_int32_t)atoi(optarg);
			break;
		case 'c':
			count = atoi(optarg);
			break;
		case 't':
			switch (optarg[0]) {
			case 'B': case 'b':
				ts = "Btree";
				type = DB_BTREE;
				break;
			case 'H': case 'h':
				if (b_util_have_hash())
					return (0);
				ts = "Hash";
				type = DB_HASH;
				break;
			case 'Q': case 'q':
				if (b_util_have_queue())
					return (0);
				ts = "Queue";
				type = DB_QUEUE;
				break;
			case 'R': case 'r':
				ts = "Recno";
				type = DB_RECNO;
				break;
			default:
				return (usage());
			}
			break;
		case '?':
		default:
			return (usage());
		}
	argc -= optind;
	argv += optind;
	if (argc != 0)
		return (usage());

	/* Create the database. */
	DB_BENCH_ASSERT(db_create(&dbp, NULL, 0) == 0);
	DB_BENCH_ASSERT(dbp->set_cachesize(dbp, 0, cachesize, 0) == 0);
	dbp->set_errfile(dbp, stderr);

	/* Set record length for Queue. */
	if (type == DB_QUEUE)
		DB_BENCH_ASSERT(dbp->set_re_len(dbp, 10) == 0);

#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1
	DB_BENCH_ASSERT(
	    dbp->open(dbp, NULL, TESTFILE, NULL, type, DB_CREATE, 0666) == 0);
#else
	DB_BENCH_ASSERT(
	    dbp->open(dbp, TESTFILE, NULL, type, DB_CREATE, 0666) == 0);
#endif

	/* Store a key/data pair. */
	memset(&key, 0, sizeof(key));
	memset(&data, 0, sizeof(data));
	switch (type) {
	case DB_BTREE:
	case DB_HASH:
		key.data = "aaaaa";
		key.size = 5;
		break;
	case DB_QUEUE:
	case DB_RECNO:
		recno = 1;
		key.data = &recno;
		key.size = sizeof(recno);
		break;
	case DB_UNKNOWN:
		b_util_abort();
		break;
	}
	data.data = "bbbbb";
	data.size = 5;

	DB_BENCH_ASSERT(dbp->put(dbp, NULL, &key, &data, 0) == 0);

	/* Retrieve the key/data pair count times. */
	TIMER_START;
	for (i = 0; i < count; ++i)
		DB_BENCH_ASSERT(dbp->get(dbp, NULL, &key, &data, 0) == 0);
	TIMER_STOP;

	printf("# %d %s database get of cached key/data item\n", count, ts);
	TIMER_DISPLAY(count);

	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0);

	return (0);
}
示例#19
0
int
b_recover(int argc, char *argv[])
{
	extern char *optarg;
	extern int optind;
	DB *dbp;
	DBT key, data;
	DB_ENV *dbenv;
	DB_TXN *txn;
	u_int32_t cachesize;
	int ch, i, count;

	/*
	 * Recover was too slow before release 4.0 that it's not worth
	 * running the test.
	 */
#if DB_VERSION_MAJOR < 4
	return (0);
#endif
	cachesize = MEGABYTE;
	count = 1000;
	while ((ch = getopt(argc, argv, "C:c:")) != EOF)
		switch (ch) {
		case 'C':
			cachesize = (u_int32_t)atoi(optarg);
			break;
		case 'c':
			count = atoi(optarg);
			break;
		case '?':
		default:
			return (usage());
		}
	argc -= optind;
	argv += optind;
	if (argc != 0)
		return (usage());

	/* Create the environment. */
	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0);
	dbenv->set_errfile(dbenv, stderr);
	DB_BENCH_ASSERT(dbenv->set_cachesize(dbenv, 0, cachesize, 0) == 0);

#define	OFLAGS								\
	(DB_CREATE | DB_INIT_LOCK |					\
	DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN | DB_PRIVATE)
#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0
	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, NULL, OFLAGS, 0666) == 0);
#endif
#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 1
	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, OFLAGS, 0666) == 0);
#endif
#if DB_VERSION_MAJOR > 3 || DB_VERSION_MINOR > 1
	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, OFLAGS, 0666) == 0);
#endif

	/* Create the database. */
	DB_BENCH_ASSERT(db_create(&dbp, dbenv, 0) == 0);
#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1
	DB_BENCH_ASSERT(dbp->open(dbp, NULL,
	    TESTFILE, NULL, DB_BTREE, DB_CREATE | DB_AUTO_COMMIT, 0666) == 0);
#else
	DB_BENCH_ASSERT(
	    dbp->open(dbp, TESTFILE, NULL, DB_BTREE, DB_CREATE, 0666) == 0);
#endif

	/* Initialize the data. */
	memset(&key, 0, sizeof(key));
	memset(&data, 0, sizeof(data));
	key.size = data.size = 20;
	key.data = data.data = "01234567890123456789";

	/* Start/commit a transaction count times. */
	for (i = 0; i < count; ++i) {
#if DB_VERSION_MAJOR < 4
		DB_BENCH_ASSERT(
		    txn_begin(dbenv, NULL, &txn, DB_TXN_NOSYNC) == 0);
		DB_BENCH_ASSERT(dbp->put(dbp, txn, &key, &data, 0) == 0);
		DB_BENCH_ASSERT(txn_commit(txn, 0) == 0);
#else
		DB_BENCH_ASSERT(
		    dbenv->txn_begin(dbenv, NULL, &txn, DB_TXN_NOSYNC) == 0);
		DB_BENCH_ASSERT(dbp->put(dbp, txn, &key, &data, 0) == 0);
		DB_BENCH_ASSERT(txn->commit(txn, 0) == 0);
#endif
	}

	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0);
	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0);

	/* Create a new DB_ENV handle. */
	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0);
	dbenv->set_errfile(dbenv, stderr);
	DB_BENCH_ASSERT(
	    dbenv->set_cachesize(dbenv, 0, 1048576 /* 1MB */, 0) == 0);

	/* Now run recovery. */
	TIMER_START;
#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0
	DB_BENCH_ASSERT(dbenv->open(
	    dbenv, TESTDIR, NULL, OFLAGS | DB_RECOVER, 0666) == 0);
#endif
#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 1
	DB_BENCH_ASSERT(
	    dbenv->open(dbenv, TESTDIR, OFLAGS | DB_RECOVER, 0666) == 0);
#endif
#if DB_VERSION_MAJOR > 3 || DB_VERSION_MINOR > 1
	DB_BENCH_ASSERT(
	    dbenv->open(dbenv, TESTDIR, OFLAGS | DB_RECOVER, 0666) == 0);
#endif
	TIMER_STOP;

	/*
	 * We divide the time by the number of transactions, so an "operation"
	 * is the recovery of a single transaction.
	 */
	printf("# recovery after %d transactions\n", count);
	TIMER_DISPLAY(count);

	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0);

	return (0);
}
int main(void)
{
  int ret, ret_c;
  u_int32_t db_flags, env_flags;
  DB *dbp;
  DB_ENV *envp;
  DBT key, data;
  DB_TXN *txn;
  const char *db_home_dir = "/tmp/mai-test-1/";
  const char *file_name = "mydb.db";
  const char keystr[BUF_SIZE];
  const char datastr[BUF_SIZE];
  int i = 0;

  dbp = NULL;
  envp = NULL;

  /* Open the environment */
  ret = db_env_create(&envp, 0);
  if (ret != 0) {
    fprintf(stderr, "Error creating environment handle: %s\n",
        db_strerror(ret));
    return (EXIT_FAILURE);
  }

  env_flags = DB_CREATE | /* Create the environment if it does
                           * not already exist. */
    DB_INIT_TXN | /* Initialize transactions */
    DB_INIT_LOCK | /* Initialize locking. */
    DB_INIT_LOG | /* Initialize logging */
    DB_INIT_MPOOL | /* Initialize the in-memory cache. */
    DB_RECOVER;
  ret = envp->open(envp, db_home_dir, env_flags, 0);
  if (ret != 0) {
    fprintf(stderr, "Error opening environment: %s\n",
        db_strerror(ret));
    goto err;
  }

  /* Initialize the DB handle */
  ret = db_create(&dbp, envp, 0);
  if (ret != 0) {
    envp->err(envp, ret, "Database creation failed");
    goto err;
  }

  db_flags = DB_CREATE | DB_AUTO_COMMIT;
  /*
     Open the database. Note that we are using auto commit for the open,
     so the database is able to support transactions.
     */
  ret = dbp->open(dbp, /* Pointer to the database */
      NULL, /* Txn pointer */
      file_name, /* File name */
      NULL, /* Logical db name */
      DB_BTREE, /* Database type (using btree) */
      db_flags, /* Open flags */
      0); /* File mode. Using defaults */
  if (ret != 0) {
    envp->err(envp, ret, "Database '%s' open failed",
        file_name);
    goto err;
  }

  /* Get the txn handle */
  txn = NULL;
  ret = envp->txn_begin(envp, NULL, &txn, 0);
  if (ret != 0) {
    envp->err(envp, ret, "Transaction begin failed.");
    goto err;
  }

  for (i = 0; i < LOOP_SIZE; i++) {
    /* Prepare the DBTs */
    memset(&key, 0, sizeof(DBT));
    memset(&data, 0, sizeof(DBT));

    sprintf((char*)keystr, "key%d", i);
    //sprintf((char*)datastr, "data%d", i);
  
    key.data = (char*)keystr;
    key.size = strlen((char*)keystr) + 1;
    //data.data = (char*)datastr;
    //data.size = strlen((char*)datastr) + 1;
  
    /* Perform the database write. If this fails, abort the transaction. */
    ret = dbp->get(dbp, txn, &key, &data, 0);
    if (ret != 0) {
      envp->err(envp, ret, "Database put failed.");
      txn->abort(txn);
      goto err;
    }
    printf("%s %s\n", key.data, data.data);
  }

  /* Commit the transaction. Note that the transaction handle
     can no longer be used. */
  ret = txn->commit(txn, 0);
  if (ret != 0) {
    envp->err(envp, ret, "Transaction commit failed.");
    goto err;
  }

err:
  /* Close the database */
  if (dbp != NULL) {
    ret_c = dbp->close(dbp, 0);
    if (ret_c != 0) {
      envp->err(envp, ret_c, "Database close failed.");
      ret = ret_c;
    }
  }

  /* Close the environment */
  if (envp != NULL) {
    ret_c = envp->close(envp, 0);
    if (ret_c != 0) {
      fprintf(stderr, "environment close failed: %s\n",
          db_strerror(ret_c));
      ret = ret_c;
    }
  }

  return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
int
main(void)
{
    /* Initialize our handles */
    DB *dbp = NULL;
    DB_ENV *envp = NULL;

    thread_t writer_threads[NUMWRITERS];
    int i, ret, ret_t;
    u_int32_t env_flags;

    /* Application name */
    const char *prog_name = "txn_guide_inmemory";

    /* Create the environment */
    ret = db_env_create(&envp, 0);
    if (ret != 0) {
	fprintf(stderr, "Error creating environment handle: %s\n",
	    db_strerror(ret));
	goto err;
    }

    env_flags =
      DB_CREATE     |  /* Create the environment if it does not exist */
      DB_INIT_LOCK  |  /* Initialize the locking subsystem */
      DB_INIT_LOG   |  /* Initialize the logging subsystem */
      DB_INIT_TXN   |  /* Initialize the transactional subsystem. This
			* also turns on logging. */
      DB_INIT_MPOOL |  /* Initialize the memory pool (in-memory cache) */
      DB_PRIVATE    |  /* Region files are backed by heap memory.  */
      DB_THREAD;       /* Cause the environment to be free-threaded */

    /* Specify in-memory logging */
    ret = envp->log_set_config(envp, DB_LOG_IN_MEMORY, 1);
    if (ret != 0) {
	fprintf(stderr, "Error setting log subsystem to in-memory: %s\n",
	    db_strerror(ret));
	goto err;
    }

    /*
     * Specify the size of the in-memory log buffer.
     */
    ret = envp->set_lg_bsize(envp, 10 * 1024 * 1024);
    if (ret != 0) {
	fprintf(stderr, "Error increasing the log buffer size: %s\n",
	    db_strerror(ret));
	goto err;
    }

    /*
     * Specify the size of the in-memory cache.
     */
    ret = envp->set_cachesize(envp, 0, 10 * 1024 * 1024, 1);
    if (ret != 0) {
	fprintf(stderr, "Error increasing the cache size: %s\n",
	    db_strerror(ret));
	goto err;
    }

     /*
     * Indicate that we want db to perform lock detection internally.
     * Also indicate that the transaction with the fewest number of
     * write locks will receive the deadlock notification in
     * the event of a deadlock.
     */
    ret = envp->set_lk_detect(envp, DB_LOCK_MINWRITE);
    if (ret != 0) {
	fprintf(stderr, "Error setting lock detect: %s\n",
	    db_strerror(ret));
	goto err;
    }

    /* Now actually open the environment */
    ret = envp->open(envp, NULL, env_flags, 0);
    if (ret != 0) {
	fprintf(stderr, "Error opening environment: %s\n",
	    db_strerror(ret));
	goto err;
    }

    /*
     * If we had utility threads (for running checkpoints or
     * deadlock detection, for example) we would spawn those
     * here. However, for a simple example such as this,
     * that is not required.
     */

    /* Open the database */
    ret = open_db(&dbp, prog_name, NULL,
      envp, DB_DUPSORT);
    if (ret != 0)
	goto err;

    /* Initialize a mutex. Used to help provide thread ids. */
    (void)mutex_init(&thread_num_lock, NULL);

    /* Start the writer threads. */
    for (i = 0; i < NUMWRITERS; i++)
	(void)thread_create(
	    &writer_threads[i], NULL, writer_thread, (void *)dbp);

    /* Join the writers */
    for (i = 0; i < NUMWRITERS; i++)
	(void)thread_join(writer_threads[i], NULL);

err:
    /* Close our database handle, if it was opened. */
    if (dbp != NULL) {
	ret_t = dbp->close(dbp, 0);
	if (ret_t != 0) {
	    fprintf(stderr, "%s database close failed.\n",
		db_strerror(ret_t));
	    ret = ret_t;
	}
    }

    /* Close our environment, if it was opened. */
    if (envp != NULL) {
	ret_t = envp->close(envp, 0);
	if (ret_t != 0) {
	    fprintf(stderr, "environment close failed: %s\n",
		db_strerror(ret_t));
		ret = ret_t;
	}
    }

    /* Final status message and return. */
    printf("I'm all done.\n");
    return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
示例#22
0
//
// Initialize the database to the specified number of accounts, branches,
// history records, and tellers.
//
int
TpcbExample::populate()
{
	DB *dbp;

	int err;
	u_int32_t balance, idnum;
	u_int32_t end_anum, end_bnum, end_tnum;
	u_int32_t start_anum, start_bnum, start_tnum;

	idnum = BEGID;
	balance = 500000;

	if ((err = db_create(&dbp, dbenv, 0)) != 0) {
		_snprintf(msgString, ERR_STRING_MAX,
		    "db_create of accounts db failed.");
		return (1);
	}
	dbp->set_h_nelem(dbp, (unsigned int)accounts);

	if ((err = dbp->open(dbp, NULL, "account", NULL, DB_HASH,
			     DB_CREATE, 0644)) != 0) {
		_snprintf(msgString, ERR_STRING_MAX,
		    "Account file create failed. error: %s.", db_strerror(err));
		return (1);
	}

	start_anum = idnum;
	if ((err =
	    populateTable(dbp, idnum, balance, accounts, "account")) != 0)
		return (1);
	idnum += accounts;
	end_anum = idnum - 1;
	if ((err = dbp->close(dbp, 0)) != 0) {
		_snprintf(msgString, ERR_STRING_MAX,
		    "Account file close failed. error: %s.", db_strerror(err));
		return (1);
	}

	if ((err = db_create(&dbp, dbenv, 0)) != 0) {
		_snprintf(msgString, ERR_STRING_MAX,
		    "db_create of branches db failed.");
		return (1);
	}
	//
	// Since the number of branches is very small, we want to use very
	// small pages and only 1 key per page.  This is the poor-man's way
	// of getting key locking instead of page locking.
	//
	dbp->set_h_ffactor(dbp, 1);
	dbp->set_h_nelem(dbp, (unsigned int)branches);
	dbp->set_pagesize(dbp, 512);

	if ((err = dbp->open(dbp, NULL, "branch", NULL, DB_HASH,
			     DB_CREATE, 0644)) != 0) {
		_snprintf(msgString, ERR_STRING_MAX,
		    "Branch file create failed. error: %s.", db_strerror(err));
		return (1);
	}
	start_bnum = idnum;
	if ((err = populateTable(dbp, idnum, balance, branches, "branch")) != 0)
		return (1);
	idnum += branches;
	end_bnum = idnum - 1;
	if ((err = dbp->close(dbp, 0)) != 0) {
		_snprintf(msgString, ERR_STRING_MAX,
		    "Close of branch file failed. error: %s.",
		    db_strerror(err));
		return (1);
	}

	if ((err = db_create(&dbp, dbenv, 0)) != 0) {
		_snprintf(msgString, ERR_STRING_MAX,
		    "db_create of teller db failed.");
		return (1);
	}
	//
	// In the case of tellers, we also want small pages, but we'll let
	// the fill factor dynamically adjust itself.
	//
	dbp->set_h_ffactor(dbp, 0);
	dbp->set_h_nelem(dbp, (unsigned int)tellers);
	dbp->set_pagesize(dbp, 512);

	if ((err = dbp->open(dbp, NULL, "teller", NULL, DB_HASH,
			     DB_CREATE, 0644)) != 0) {
		_snprintf(msgString, ERR_STRING_MAX,
		    "Teller file create failed. error: %s.", db_strerror(err));
		return (1);
	}

	start_tnum = idnum;
	if ((err = populateTable(dbp, idnum, balance, tellers, "teller")) != 0)
		return (1);
	idnum += tellers;
	end_tnum = idnum - 1;
	if ((err = dbp->close(dbp, 0)) != 0) {
		_snprintf(msgString, ERR_STRING_MAX,
		    "Close of teller file failed. error: %s.",
		    db_strerror(err));
		return (1);
	}

	if ((err = db_create(&dbp, dbenv, 0)) != 0) {
		_snprintf(msgString, ERR_STRING_MAX,
		    "db_create of history db failed.");
		return (1);
	}
	dbp->set_re_len(dbp, HISTORY_LEN);
	if ((err = dbp->open(dbp, NULL, "history", NULL, DB_RECNO,
			     DB_CREATE, 0644)) != 0) {
		_snprintf(msgString, ERR_STRING_MAX,
		    "Create of history file failed. error: %s.",
		    db_strerror(err));
		return (1);
	}

	populateHistory(dbp, history, accounts, branches, tellers);
	if ((err = dbp->close(dbp, 0)) != 0) {
		_snprintf(msgString, ERR_STRING_MAX,
		    "Close of history file failed. error: %s.",
		    db_strerror(err));
		return (1);
	}

	_snprintf(msgString, ERR_STRING_MAX, "Populated OK.");
	return (0);
}
示例#23
0
DB*
CONCORD_BDB_open (const char* db_dir,
		  const char* genre,
		  const char* key_type,
		  const char* name,
		  DBTYPE real_subtype,
		  u_int32_t accessmask, int modemask)
{
  DB* dbase;
  int status;
  int len, name_len, i;
  int size;
  char *db_file_name, *sp;
  struct stat statbuf;

  status = db_create (&dbase, NULL, 0);
  if (status)
    return NULL;

  if ( (accessmask & DB_CREATE) && stat (db_dir, &statbuf) )
    mkdir (db_dir, modemask);

  len = strlen (db_dir);
  name_len = strlen (name);
  size = len + strlen (genre) + strlen (key_type) + name_len * 3 + 5;
  db_file_name = alloca (size);
  strcpy (db_file_name, db_dir);
  if (db_file_name[len - 1] != '/')
    {
      db_file_name[len++] = '/';
      db_file_name[len] = '\0';
    }

  strcat (db_file_name, genre);
  if ( (accessmask & DB_CREATE) && stat (db_file_name, &statbuf) )
    mkdir (db_file_name, modemask);
  strcat (db_file_name, "/");

  strcat (db_file_name, key_type);
  if ( (accessmask & DB_CREATE) && stat (db_file_name, &statbuf) )
    mkdir (db_file_name, modemask);
  strcat (db_file_name, "/");

  /* strcat (db_file_name, name); */
  sp = &db_file_name[strlen (db_file_name)];
  for (i = 0; i < name_len; i++)
    {
      int c = name[i];

      if ( /* (c == '/') || (c == '%') */
	  strchr ("%/\\:*?\"<>|", c) != NULL )
	{
	  sprintf (sp, "%%%02X", c);
	  sp += 3;
	}
      else
	*sp++ = c;
    }
  *sp = '\0';
#if DB_VERSION_MAJOR < 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 1)
  status = dbase->open (dbase, db_file_name, NULL,
			real_subtype, accessmask, modemask);
#else /* DB_VERSION >= 4.1 */
  status = dbase->open (dbase, NULL, db_file_name, NULL,
			real_subtype,
			accessmask /* | DB_AUTO_COMMIT */, modemask);
#endif /* DB_VERSION < 4.1 */
  if (status)
    {
      dbase->close (dbase, 0);
      return NULL;
    }
  return dbase;
}
示例#24
0
文件: b_del.c 项目: mcandre/db
int
b_del(int argc, char *argv[])
{
	extern char *optarg;
	extern int optind, __db_getopt_reset;
	DB *dbp;
	DBC *dbc;
	DBT key, data;
	DBTYPE type;
#if DB_VERSION_MAJOR > 5 || (DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR >= 2)
	DB_HEAP_RID rid;
#endif
	db_recno_t recno;
	u_int32_t cachesize;
	int ch, i, count, ret, use_cursor;
	char *ts, buf[32];

	type = DB_BTREE;
	cachesize = MEGABYTE;
	count = 100000;
	use_cursor = 0;
	ts = "Btree";
	__db_getopt_reset = 1;
	while ((ch = getopt(argc, argv, "C:c:t:w")) != EOF)
		switch (ch) {
		case 'C':
			cachesize = (u_int32_t)atoi(optarg);
			break;
		case 'c':
			count = atoi(optarg);
			break;
		case 't':
			switch (optarg[0]) {
			case 'B': case 'b':
				ts = "Btree";
				type = DB_BTREE;
				break;
			case 'H': case 'h':
				if (optarg[1] == 'E' || optarg[1] == 'e') {
#if DB_VERSION_MAJOR > 5 || (DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR >= 2)
					if (b_util_have_heap())
						return (0);
					ts = "Heap";
					type = DB_HEAP;
#else
					fprintf(stderr,
				"b_curwalk: Heap is not supported! \n");
					return (EXIT_SUCCESS);
#endif
				} else {
					if (b_util_have_hash())
						return (0);
					ts = "Hash";
					type = DB_HASH;
				}
				break;
			case 'Q': case 'q':
				if (b_util_have_queue())
					return (0);
				ts = "Queue";
				type = DB_QUEUE;
				break;
			case 'R': case 'r':
				ts = "Recno";
				type = DB_RECNO;
				break;
			default:
				return (b_del_usage());
			}
			break;
		case 'w':
			use_cursor = 1;
			break;
		case '?':
		default:
			return (b_del_usage());
		}
	argc -= optind;
	argv += optind;
	if (argc != 0)
		return (b_del_usage());

	/* Create the database. */
	DB_BENCH_ASSERT(db_create(&dbp, NULL, 0) == 0);
	DB_BENCH_ASSERT(dbp->set_cachesize(dbp, 0, cachesize, 0) == 0);
	dbp->set_errfile(dbp, stderr);

#if DB_VERSION_MAJOR > 5 || (DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR >= 2)
	/* Need a cursor if using Heap. */
	if (type == DB_HEAP && !use_cursor) {
		printf("Heap databases require the -w flag.\n");
		return (-1);
	}
#endif

	/* Set record length for Queue. */
	if (type == DB_QUEUE)
		DB_BENCH_ASSERT(dbp->set_re_len(dbp, 20) == 0);

#if DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)
	DB_BENCH_ASSERT(
	    dbp->open(dbp, NULL, TESTFILE, NULL, type, DB_CREATE, 0666) == 0);
#else
	DB_BENCH_ASSERT(
	    dbp->open(dbp, TESTFILE, NULL, type, DB_CREATE, 0666) == 0);
#endif

	/* Initialize the data. */
	memset(&key, 0, sizeof(key));
	memset(&data, 0, sizeof(data));
	data.data = "01234567890123456789";
	data.size = 20;

	/* Store a key/data pair. */
	switch (type) {
	case DB_BTREE:
	case DB_HASH:
		key.data = buf;
		key.size = 10;
		break;
#if DB_VERSION_MAJOR > 5 || (DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR >= 2)
	case DB_HEAP:
		key.data = &rid;
		key.size = sizeof(rid);
		break;
#endif
	case DB_QUEUE:
	case DB_RECNO:
		key.data = &recno;
		key.size = sizeof(recno);
		break;
	case DB_UNKNOWN:
		b_util_abort();
		break;
	}

	/* Insert count in-order key/data pairs. */
	if (type == DB_BTREE || type == DB_HASH)
		for (i = 0; i < count; ++i) {
			(void)snprintf(buf, sizeof(buf), "%010d", i);
			DB_BENCH_ASSERT(
			    dbp->put(dbp, NULL, &key, &data, 0) == 0);
		}
#if DB_VERSION_MAJOR > 5 || (DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR >= 2)
	else if (type == DB_HEAP)
		for (i = 0; i < count; i++)
			DB_BENCH_ASSERT(
			    dbp->put(dbp, NULL, &key, &data, DB_APPEND) == 0);
#endif
	else
		for (i = 0, recno = 1; i < count; ++i, ++recno)
			DB_BENCH_ASSERT(
			    dbp->put(dbp, NULL, &key, &data, 0) == 0);

	/* Delete the records. */
	TIMER_START;
	if (use_cursor) {
		DB_BENCH_ASSERT(dbp->cursor(dbp, NULL, &dbc, 0) == 0);
		while ((ret = dbc->c_get(dbc, &key, &data, DB_NEXT)) == 0)
			DB_BENCH_ASSERT(dbc->c_del(dbc, 0) == 0);
		DB_BENCH_ASSERT (ret == DB_NOTFOUND);
	} else
		if (type == DB_BTREE || type == DB_HASH)
			for (i = 0; i < count; ++i) {
				(void)snprintf(buf, sizeof(buf), "%010d", i);
				DB_BENCH_ASSERT(
				    dbp->del(dbp, NULL, &key, 0) == 0);
			}
		else
			for (i = 0, recno = 1; i < count; ++i, ++recno)
				DB_BENCH_ASSERT(
				    dbp->del(dbp, NULL, &key, 0) == 0);

	TIMER_STOP;

	printf(
    "# %d %s database in-order delete of 10/20 byte key/data pairs using %s\n",
	    count, ts, use_cursor ? "a cursor" : "the key");
	TIMER_DISPLAY(count);

	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0);

	return (0);
}
示例#25
0
/*
 * Getent implements the functions of cgetent.  If fp is non-NULL,
 * *db_array has already been opened and fp is the open file descriptor.  We
 * do this to save time and avoid using up file descriptors for tc=
 * recursions.
 *
 * Getent returns the same success/failure codes as cgetent.  On success, a
 * pointer to a malloc'ed capability record with all tc= capabilities fully
 * expanded and its length (not including trailing ASCII NUL) are left in
 * *cap and *len.
 *
 * Basic algorithm:
 *	+ Allocate memory incrementally as needed in chunks of size BFRAG
 *	  for capability buffer.
 *	+ Recurse for each tc=name and interpolate result.  Stop when all
 *	  names interpolated, a name can't be found, or depth exceeds
 *	  MAX_RECURSION.
 */
static int
getent(char **cap, u_int *len, char **db_array, FILE *fp,
	const char *name, int depth, char *nfield)
{
	DB *capdbp;
	char *r_end, *rp, **db_p;
	int myfd, eof, foundit, opened, retval, clen;
	char *record, *cbuf;
	int tc_not_resolved;
	char pbuf[PATH_MAX];

	/*
	 * Return with ``loop detected'' error if we've recursed more than
	 * MAX_RECURSION times.
	 */
	if (depth > MAX_RECURSION)
		return (-3);

	opened = 0;

	/*
	 * Check if we have a top record from cgetset().
	 */
	if (depth == 0 && toprec != NULL && cgetmatch(toprec, name) == 0) {
		opened++;
		if ((record = malloc(topreclen + 1 + BFRAG)) == NULL)
			return (-2);
		memcpy(record, toprec, topreclen + 1);
		myfd = 0;
		db_p = db_array;
		rp = record + topreclen + 1;
		r_end = rp + BFRAG;
		goto tc_exp;
	}
	/*
	 * Allocate first chunk of memory.
	 */
	if ((record = malloc(BFRAG)) == NULL)
		return (-2);
	r_end = record + BFRAG;
	foundit = 0;
	/*
	 * Loop through database array until finding the record.
	 */

	for (db_p = db_array; *db_p != NULL; db_p++) {
		eof = 0;

		/*
		 * Open database if not already open.
		 */
		if (fp != NULL) {
			(void)fseek(fp, 0L, SEEK_SET);
			myfd = 0;
			opened++;
		} else {
			char *dbrecord;

			clen = snprintf(pbuf, sizeof(pbuf), "%s.db", *db_p);
			if (clen != -1 && clen < sizeof(pbuf) && usedb &&
			    (capdbp = dbopen(pbuf, O_RDONLY, 0, DB_HASH, 0))) {
				opened++;
				retval = cdbget(capdbp, &dbrecord, name);
				if (retval < 0) {
					/* no record available */
					(void)capdbp->close(capdbp);
					continue;
				}
				free(record);
				/* save the data; close frees it */
				clen = strlen(dbrecord);
				if ((cbuf = malloc(clen + 1)) == NULL)
					return (-2);
				memcpy(cbuf, dbrecord, clen + 1);
				if (capdbp->close(capdbp) < 0) {
					free(cbuf);
					return (-2);
				}
				/* assume tc='s have been expanded??? */
				*len = clen;
				*cap = cbuf;
				return (retval);
			} else {
				fp = fopen(*db_p, "re");
				if (fp == NULL) {
					/* No error on unfound file. */
					continue;
				}
				myfd = 1;
				opened++;
			}
		}
		/*
		 * Find the requested capability record ...
		 */
		{
		    char buf[BUFSIZ];
		    char *b_end, *bp;
		    int c;

		    /*
		     * Loop invariants:
		     *	There is always room for one more character in record.
		     *	R_end always points just past end of record.
		     *	Rp always points just past last character in record.
		     *	B_end always points just past last character in buf.
		     *	Bp always points at next character in buf.
		     */
		    b_end = buf;
		    bp = buf;
		    for (;;) {

			/*
			 * Read in a line implementing (\, newline)
			 * line continuation.
			 */
			rp = record;
			for (;;) {
				if (bp >= b_end) {
					size_t n;

					n = fread(buf, 1, sizeof(buf), fp);
					if (n == 0) {
						eof = feof(fp);
						if (myfd)
							(void)fclose(fp);
						if (eof) {
							fp = NULL;
							break;
						}
						free(record);
						return (-2);
					}
					b_end = buf+n;
					bp = buf;
				}

				c = *bp++;
				if (c == '\n') {
					if (rp > record && *(rp-1) == '\\') {
						rp--;
						continue;
					} else
						break;
				}
				*rp++ = c;

				/*
				 * Enforce loop invariant: if no room
				 * left in record buffer, try to get
				 * some more.
				 */
				if (rp >= r_end) {
					size_t pos;
					size_t newsize;
					char *nrecord;

					pos = rp - record;
					newsize = r_end - record + BFRAG;
					nrecord = realloc(record, newsize);
					if (nrecord == NULL) {
						free(record);
						if (myfd)
							(void)fclose(fp);
						errno = ENOMEM;
						return (-2);
					}
					record = nrecord;
					r_end = record + newsize;
					rp = record + pos;
				}
			}
				/* loop invariant lets us do this */
			*rp++ = '\0';

			/*
			 * If encountered EOF check next file.
			 */
			if (eof)
				break;

			/*
			 * Toss blank lines and comments.
			 */
			if (*record == '\0' || *record == '#')
				continue;

			/*
			 * See if this is the record we want ...
			 */
			if (cgetmatch(record, name) == 0) {
				if (nfield == NULL || !nfcmp(nfield, record)) {
					foundit = 1;
					break;	/* found it! */
				}
			}
		    }
		}
		if (foundit)
			break;
	}

	if (!foundit) {
		free(record);
		return (opened ? -1 : -2);
	}

	/*
	 * Got the capability record, but now we have to expand all tc=name
	 * references in it ...
	 */
tc_exp:	{
		char *s;
		u_int ilen;
		int diff, iret, tclen;
		char *ibuf, *icap, *scan, *tc, *tcstart, *tcend;

		/*
		 * Loop invariants:
		 *	There is room for one more character in record.
		 *	R_end points just past end of record.
		 *	Rp points just past last character in record.
		 *	Scan points at remainder of record that needs to be
		 *	scanned for tc=name constructs.
		 */
		scan = record;
		tc_not_resolved = 0;
		for (;;) {
			if ((tc = cgetcap(scan, "tc", '=')) == NULL)
				break;

			/*
			 * Find end of tc=name and stomp on the trailing `:'
			 * (if present) so we can use it to call ourselves.
			 */
			s = tc;
			for (;;) {
				if (*s == '\0')
					break;
				else
					if (*s++ == ':') {
						*(s - 1) = '\0';
						break;
					}
			}
			tcstart = tc - 3;
			tclen = s - tcstart;
			tcend = s;

			iret = getent(&icap, &ilen, db_p, fp, tc, depth+1,
				      NULL);
			if (iret != 0) {
				/* an error */
				if (iret < -1) {
					if (myfd)
						(void)fclose(fp);
					free(record);
					return (iret);
				}
				if (iret == 1)
					tc_not_resolved = 1;
				/* couldn't resolve tc */
				if (iret == -1) {
					*(s - 1) = ':';
					scan = s - 1;
					tc_not_resolved = 1;
					continue;

				}
			}
			/* not interested in name field of tc'ed record */
			s = ibuf = icap;
			for (;;)
				if (*s == '\0')
					break;
				else
					if (*s++ == ':')
						break;
			ilen -= s - icap;
			icap = s;

			/* make sure interpolated record is `:'-terminated */
			s += ilen;
			if (*(s-1) != ':') {
				*s = ':';	/* overwrite NUL with : */
				ilen++;
			}

			/*
			 * Make sure there's enough room to insert the
			 * new record.
			 */
			diff = ilen - tclen;
			if (diff >= r_end - rp) {
				u_int pos, tcpos, tcposend;
				size_t newsize;
				char *nrecord;

				pos = rp - record;
				newsize = r_end - record + diff + BFRAG;
				tcpos = tcstart - record;
				tcposend = tcend - record;
				nrecord = realloc(record, newsize);
				if (nrecord == NULL) {
					free(record);
					if (myfd)
						(void)fclose(fp);
					free(ibuf);
					errno = ENOMEM;
					return (-2);
				}
				record = nrecord;
				r_end = record + newsize;
				rp = record + pos;
				tcstart = record + tcpos;
				tcend = record + tcposend;
			}

			/*
			 * Insert tc'ed record into our record.
			 */
			s = tcstart + ilen;
			memmove(s, tcend, rp - tcend);
			memmove(tcstart, icap, ilen);
			rp += diff;
			free(ibuf);

			/*
			 * Start scan on `:' so next cgetcap works properly
			 * (cgetcap always skips first field).
			 */
			scan = s-1;
		}

	}
	/*
	 * Close file (if we opened it), give back any extra memory, and
	 * return capability, length and success.
	 */
	if (myfd)
		(void)fclose(fp);
	*len = rp - record - 1;	/* don't count NUL */
	if (r_end > rp) {
		char *nrecord;

		if ((nrecord = realloc(record, rp - record)) == NULL) {
			free(record);
			errno = ENOMEM;
			return (-2);
		}
		record = nrecord;
	}
	*cap = record;
	if (tc_not_resolved)
		return (1);
	return (0);
}
示例#26
0
/*
 *  worker function shared between top10Users and top10Groups
 *
 *  Creates in-memory only database to store temporary results
 *  as long as done == FALSE.  As soon as done is set to TRUE,
 *  generate the top10 lists for the database.
 *
 *  The results parameter is used to pass the database pointer around
 *  while calculating, then changes to an agg_type_t when complete.
 *
 */
static int
do_top10(filinfo_t *filinfo, filvar_t *filvar, boolean_t done,	/* ARGSUSED */
         fm_rptno_t which, fmFuncRes_t *results)
{
    int		st;
    DB		*dbp;
    DBC		*curs;
    DBT		key;
    DBT		data;
    DB_TXN		*txn = NULL;
    agg_size_t	agg;
    agg_list_t	*agglist = NULL;
    agg_size_t	*aggp;
    int		i;
    agg_size_t	*aggreport;

    dbp = results->rptDB;

    if (done == FALSE) {
        if ((filinfo == NULL) || (filvar == NULL)) {
            return (-1);
        }

        if (dbp == NULL) {
            st = db_create(&dbp, dbEnv, 0);
            if (st != 0) {
                return (st);
            }
            /* no duplicates, sort on id */
            st = dbp->set_bt_compare(dbp, bt_compare_uint64);
            if (st != 0) {
                dbp->remove(dbp, NULL, NULL, 0);
                return (st);
            }

            st = dbp->open(dbp, NULL, NULL, NULL, DB_BTREE,
                           db_fl, 0644);
            if (st != 0) {
                dbp->remove(dbp, NULL, NULL, 0);
                return (st);
            }

            results->rptDB = dbp;
        }

        memset(&agg, 0, sizeof (agg_size_t));

        if (which == TOP_USERS) {
            agg.id = filinfo->owner;
        } else {
            agg.id = filinfo->group;
        }

        /* fetch id info if it exists */
        memset(&key, 0, sizeof (DBT));
        memset(&data, 0, sizeof (DBT));

        key.data = &agg.id;
        key.size = sizeof (uint64_t);

        data.data = &agg;
        data.size = data.ulen = sizeof (agg_size_t);
        data.flags = DB_DBT_USERMEM;

        dbEnv->txn_begin(dbEnv, NULL, &txn, 0);
        st = dbp->get(dbp, txn, &key, &data, 0);

        if ((st != 0) && (st != DB_NOTFOUND)) {
            txn->abort(txn);
            return (st);
        }

        agg.count++;
        agg.total_size += filinfo->size;
        agg.total_osize += filinfo->osize;

        st = dbp->put(dbp, txn, &key, &data, 0);
        if (st == 0) {
            st = txn->commit(txn, 0);
        } else {
            txn->abort(txn);
        }
    }

    /* final processing */
    if (done == TRUE) {
        uint64_t	aggid = 0;
        int 		numids = 0;
        agg_list_t	*aggent;
        agg_list_t	*ptr;
        agg_list_t	*last;

        if (dbp == NULL) {
            return (-1);
        }

        dbEnv->txn_begin(dbEnv, NULL, &txn, 0);

        st = dbp->cursor(dbp, txn, &curs, 0);
        if (st != 0) {
            /* blast db? */
            txn->abort(txn);
            return (st);
        }

        memset(&key, 0, sizeof (DBT));
        memset(&data, 0, sizeof (DBT));

        key.data = &aggid;
        key.size = key.ulen = sizeof (uint64_t);
        key.flags = DB_DBT_USERMEM;

        data.flags = DB_DBT_MALLOC;

        /* fetch first entry */
        while ((st = curs->c_get(curs, &key, &data, DB_NEXT)) == 0) {
            aggp = (agg_size_t *)data.data;
            last = NULL;

            if (agglist == NULL) {
                aggent = malloc(sizeof (agg_list_t));
                aggent->agg = aggp;

                aggent->prev = NULL;
                aggent->next = NULL;
                agglist = aggent;

                numids = 1;
                continue;
            }

            ptr = agglist;

            while (ptr != NULL) {
                last = ptr;
                if (aggp->total_size >
                        ptr->agg->total_size) {
                    break;
                }
                ptr = ptr->next;
            }

            if ((ptr != NULL) || (numids < 10)) {
                aggent = malloc(sizeof (agg_list_t));
                if (aggent == NULL) {
                    st = ENOMEM;
                    goto done;
                }
                aggent->agg = aggp;
                aggent->next = ptr;
                if (ptr != NULL) {
                    aggent->prev = ptr->prev;
                    if (ptr->prev != NULL) {
                        ptr->prev->next = aggent;
                    }
                    ptr->prev = aggent;
                } else {
                    aggent->prev = last;
                    if (last != NULL) {
                        last->next = aggent;
                    }
                }

                if (aggent->prev == NULL) {
                    agglist = aggent;
                }
                numids++;
                aggp = NULL;
            }

            if (numids > 10) {
                ptr = agglist;

                while (ptr->next != NULL) {
                    ptr = ptr->next;
                }

                free(ptr->agg);
                ptr->prev->next = NULL;
                free(ptr);
                numids--;
            }

            if (aggp != NULL) {
                free(aggp);
            }
        }

        /* done with the in-mem database now */
        (void) curs->c_close(curs);
        (void) txn->commit(txn, 0);

        (void) dbp->close(dbp, 0);
        results->rptDB = NULL;

        if ((st != 0) && (st != DB_NOTFOUND)) {
            /* something bad happened */
            goto done;
        }

        /* got the top 10, allocate the final structure */
        results->rptSize = 10 * (sizeof (agg_size_t));
        aggreport = calloc(1, results->rptSize);
        results->result = (void *)aggreport;

        if (aggreport == NULL) {
            st = ENOMEM;
            goto done;
        }

        ptr = agglist;

        for (i = 0; ptr != NULL; i++) {
            aggp = ptr->agg;
            memcpy(&aggreport[i], aggp, sizeof (agg_size_t));
            ptr = ptr->next;
        }

        st = 0;
done:
        while (agglist != NULL) {
            ptr = agglist;
            agglist = ptr->next;

            free(ptr->agg);
            free(ptr);
        }

    }

    return (st);
}
示例#27
0
static int
db_servent(void *retval, void *mdata, va_list ap)
{
	char buf[BUFSIZ];
	DBT key, data, *result;
	DB *db;

	struct db_state *st;
	int rv;
	int stayopen;

	enum nss_lookup_type how;
	char *name;
	char *proto;
	int port;

	struct servent *serv;
	char *buffer;
	size_t bufsize;
	int *errnop;

	name = NULL;
	proto = NULL;
	how = (enum nss_lookup_type)mdata;
	switch (how) {
	case nss_lt_name:
		name = va_arg(ap, char *);
		proto = va_arg(ap, char *);
		break;
	case nss_lt_id:
		port = va_arg(ap, int);
		proto = va_arg(ap, char *);
		break;
	case nss_lt_all:
		break;
	default:
		return NS_NOTFOUND;
	};

	serv = va_arg(ap, struct servent *);
	buffer  = va_arg(ap, char *);
	bufsize = va_arg(ap, size_t);
	errnop = va_arg(ap,int *);

	*errnop = db_getstate(&st);
	if (*errnop != 0)
		return (NS_UNAVAIL);

	if (how == nss_lt_all && st->keynum < 0)
		return (NS_NOTFOUND);

	if (st->db == NULL) {
		st->db = dbopen(_PATH_SERVICES_DB, O_RDONLY, 0, DB_HASH, NULL);
		if (st->db == NULL) {
			*errnop = errno;
			return (NS_UNAVAIL);
		}
	}

	stayopen = (how == nss_lt_all) ? 1 : st->stayopen;
	db = st->db;

	do {
		switch (how) {
		case nss_lt_name:
			key.data = buf;
			if (proto == NULL)
				key.size = snprintf(buf, sizeof(buf),
				    "\376%s", name);
			else
				key.size = snprintf(buf, sizeof(buf),
				    "\376%s/%s", name, proto);
			key.size++;
			if (db->get(db, &key, &data, 0) != 0 ||
			    db->get(db, &data, &key, 0) != 0) {
				rv = NS_NOTFOUND;
				goto db_fin;
			}
			result = &key;
			break;
		case nss_lt_id:
			key.data = buf;
			port = htons(port);
			if (proto == NULL)
				key.size = snprintf(buf, sizeof(buf),
				    "\377%d", port);
			else
				key.size = snprintf(buf, sizeof(buf),
				    "\377%d/%s", port, proto);
			key.size++;
			if (db->get(db, &key, &data, 0) != 0 ||
			    db->get(db, &data, &key, 0) != 0) {
				rv = NS_NOTFOUND;
				goto db_fin;
			}
			result = &key;
			break;
		case nss_lt_all:
			key.data = buf;
			key.size = snprintf(buf, sizeof(buf), "%d",
			    st->keynum++);
			key.size++;
			if (db->get(db, &key, &data, 0) != 0) {
				st->keynum = -1;
				rv = NS_NOTFOUND;
				goto db_fin;
			}
			result = &data;
			break;
		}

		rv = parse_result(serv, buffer, bufsize, result->data,
		    result->size - 1, errnop);

	} while (!(rv & NS_TERMINATE) && how == nss_lt_all);

db_fin:
	if (!stayopen && st->db != NULL) {
		db->close(db);
		st->db = NULL;
	}

	if (rv == NS_SUCCESS && retval != NULL)
		*(struct servent **)retval = serv;

	return (rv);
}
示例#28
0
文件: db3.c 项目: crossbuild/rpm
static int db3_dbiOpen(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int flags)
{
    const char *dbhome = rpmdbHome(rdb);
    dbiIndex dbi = NULL;
    int rc = 0;
    int retry_open;
    int verifyonly = (flags & RPMDB_FLAG_VERIFYONLY);

    DB * db = NULL;
    DBTYPE dbtype = DB_UNKNOWN;
    uint32_t oflags;
    static int _lockdbfd = 0;

    if (dbip)
	*dbip = NULL;

    if ((dbi = dbiNew(rdb, rpmtag)) == NULL)
	return 1;

    /*
     * Parse db configuration parameters.
     */
    dbConfigure(rpmtag, rdb->db_dbenv == NULL ? &rdb->cfg : NULL, &dbi->cfg);

    /*
     * Map open mode flags onto configured database/environment flags.
     */
    oflags = dbi->cfg.dbi_oflags;
    if ((rdb->db_mode & O_ACCMODE) == O_RDONLY)
	oflags |= DB_RDONLY;

    rc = db_init(rdb, dbhome);

    retry_open = (rc == 0) ? 2 : 0;

    while (retry_open) {
	rc = db_create(&db, rdb->db_dbenv, 0);
	rc = cvtdberr(dbi, "db_create", rc, _debug);

	/* For verify we only want the handle, not an open db */
	if (verifyonly)
	    break;

	if (rc == 0 && db != NULL) {
	    int _printit;
	    char *dbfs = prDbiOpenFlags(oflags, 0);
	    rpmlog(RPMLOG_DEBUG, "opening  db index       %s/%s %s mode=0x%x\n",
		    dbhome, dbi->dbi_file, dbfs, rdb->db_mode);
	    free(dbfs);

	    rc = (db->open)(db, NULL, dbi->dbi_file, NULL,
			    dbtype, oflags, rdb->db_perms);

	    /* Attempt to create if missing, discarding DB_RDONLY (!) */
	    if (rc == ENOENT) {
		oflags |= DB_CREATE;
		oflags &= ~DB_RDONLY;
		dbtype = (rpmtag == RPMDBI_PACKAGES) ?  DB_HASH : DB_BTREE;
		retry_open--;
	    } else {
		retry_open = 0;
	    }

	    /* XXX return rc == errno without printing */
	    _printit = (rc > 0 ? 0 : _debug);
	    rc = cvtdberr(dbi, "db->open", rc, _printit);

	    /* Validate the index type is something we can support */
	    if ((rc == 0) && (dbtype == DB_UNKNOWN)) {
		db->get_type(db, &dbtype);
		if (dbtype != DB_HASH && dbtype != DB_BTREE) {
		    rpmlog(RPMLOG_ERR, _("invalid index type %x on %s/%s\n"),
				dbtype, dbhome, dbi->dbi_file);
		    rc = 1;
		}
	    }

	    if (rc != 0) {
		db->close(db, 0);
		db = NULL;
	    }
	}
    }

    dbi->dbi_db = db;

    dbi->dbi_flags = 0;
    if (oflags & DB_CREATE)
	dbi->dbi_flags |= DBI_CREATED;
    if (oflags & DB_RDONLY)
	dbi->dbi_flags |= DBI_RDONLY;

    if (!verifyonly && rc == 0 && dbi->cfg.dbi_lockdbfd && _lockdbfd++ == 0) {
	rc = dbiFlock(dbi, rdb->db_mode);
    }

    if (rc == 0 && dbi->dbi_db != NULL && dbip != NULL) {
	*dbip = dbi;
    } else {
	(void) dbiClose(dbi, 0);
    }

    return rc;
}
int
dbupdate(char *dbname, char *ip)
{
	HASHINFO	hashinfo;
	DBT		dbk, dbd;
	DB		*db;
	struct gdata	gd;
	time_t		now;
	int		r;
	struct in_addr	ia;

	now = time(NULL);
	memset(&hashinfo, 0, sizeof(hashinfo));
	db = dbopen(dbname, O_EXLOCK|O_RDWR, 0600, DB_HASH, &hashinfo);
	if (db == NULL) {
		logmsg(LOG_ERR, "Can not open db %s: %s", dbname,
		    strerror(errno));
		return (-1);
	}
	if (inet_pton(AF_INET, ip, &ia) != 1) {
		logmsg(LOG_NOTICE, "Invalid IP address %s", ip);
		goto bad;
	}
	memset(&dbk, 0, sizeof(dbk));
	dbk.size = strlen(ip);
	dbk.data = ip;
	memset(&dbd, 0, sizeof(dbd));

	/* add or update whitelist entry */
	r = db->get(db, &dbk, &dbd, 0);
	if (r == -1) {
		logmsg(LOG_NOTICE, "db->get failed (%m)");
		goto bad;
	}

	if (r) {
		/* new entry */
		memset(&gd, 0, sizeof(gd));
		gd.first = now;
		gd.bcount = 1;
		gd.pass = now;
		gd.expire = now + whiteexp;
		memset(&dbk, 0, sizeof(dbk));
		dbk.size = strlen(ip);
		dbk.data = ip;
		memset(&dbd, 0, sizeof(dbd));
		dbd.size = sizeof(gd);
		dbd.data = &gd;
		r = db->put(db, &dbk, &dbd, 0);
		if (r) {
			logmsg(LOG_NOTICE, "db->put failed (%m)");
			goto bad;
		}
	} else {
		if (dbd.size != sizeof(gd)) {
			/* whatever this is, it doesn't belong */
			db->del(db, &dbk, 0);
			goto bad;
		}
		memcpy(&gd, dbd.data, sizeof(gd));
		gd.pcount++;
		gd.expire = now + whiteexp;
		memset(&dbk, 0, sizeof(dbk));
		dbk.size = strlen(ip);
		dbk.data = ip;
		memset(&dbd, 0, sizeof(dbd));
		dbd.size = sizeof(gd);
		dbd.data = &gd;
		r = db->put(db, &dbk, &dbd, 0);
		if (r) {
			logmsg(LOG_NOTICE, "db->put failed (%m)");
			goto bad;
		}
	}
	db->close(db);
	db = NULL;
	if (syncsend)
		sync_white(now, now + whiteexp, ip);
	return (0);
 bad:
	db->close(db);
	db = NULL;
	return (-1);
}
示例#30
0
文件: ex_btrec.c 项目: kanbang/Colt
int
ex_btrec()
{
	DB *dbp;
	DBC *dbcp;
	DBT key, data;
	DB_BTREE_STAT *statp;
	FILE *fp;
	db_recno_t recno;
	size_t len;
	int cnt, ret;
	char *p, *t, buf[1024], rbuf[1024];
	const char *progname = "ex_btrec";		/* Program name. */

	/* Open the word database. */
	if ((fp = fopen(WORDLIST, "r")) == NULL) {
		fprintf(stderr, "%s: open %s: %s\n",
		    progname, WORDLIST, db_strerror(errno));
		return (1);
	}

	/* Remove the previous database. */
	(void)remove(DATABASE);

	/* Create and initialize database object, open the database. */
	if ((ret = db_create(&dbp, NULL, 0)) != 0) {
		fprintf(stderr,
		    "%s: db_create: %s\n", progname, db_strerror(ret));
		return (1);
	}
	dbp->set_errfile(dbp, stderr);
	dbp->set_errpfx(dbp, progname);			/* 1K page sizes. */
	if ((ret = dbp->set_pagesize(dbp, 1024)) != 0) {
		dbp->err(dbp, ret, "set_pagesize");
		return (1);
	}						/* Record numbers. */
	if ((ret = dbp->set_flags(dbp, DB_RECNUM)) != 0) {
		dbp->err(dbp, ret, "set_flags: DB_RECNUM");
		return (1);
	}
	if ((ret = dbp->open(dbp,
	    NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
		dbp->err(dbp, ret, "open: %s", DATABASE);
		return (1);
	}

	/*
	 * Insert records into the database, where the key is the word
	 * preceded by its record number, and the data is the same, but
	 * in reverse order.
	 */
	memset(&key, 0, sizeof(DBT));
	memset(&data, 0, sizeof(DBT));
	for (cnt = 1; cnt <= 1000; ++cnt) {
		(void)sprintf(buf, "%04d_", cnt);
		if (fgets(buf + 4, sizeof(buf) - 4, fp) == NULL)
			break;
		len = strlen(buf);
		for (t = rbuf, p = buf + (len - 2); p >= buf;)
			*t++ = *p--;
		*t++ = '\0';

		key.data = buf;
		data.data = rbuf;
		data.size = key.size = (u_int32_t)len - 1;

		if ((ret =
		    dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE)) != 0) {
			dbp->err(dbp, ret, "DB->put");
			if (ret != DB_KEYEXIST)
				goto err1;
		}
	}

	/* Close the word database. */
	(void)fclose(fp);

	/* Print out the number of records in the database. */
	if ((ret = dbp->stat(dbp, NULL, &statp, 0)) != 0) {
		dbp->err(dbp, ret, "DB->stat");
		goto err1;
	}
	printf("%s: database contains %lu records\n",
	    progname, (u_long)statp->bt_ndata);
	free(statp);

	/* Acquire a cursor for the database. */
	if ((ret = dbp->cursor(dbp, NULL, &dbcp, 0)) != 0) {
		dbp->err(dbp, ret, "DB->cursor");
		goto err1;
	}

	/*
	 * Prompt the user for a record number, then retrieve and display
	 * that record.
	 */
	for (;;) {
		/* Get a record number. */
		printf("recno #> ");
		fflush(stdout);
		if (fgets(buf, sizeof(buf), stdin) == NULL)
			break;
		recno = atoi(buf);

		/*
		 * Reset the key each time, the dbp->get() routine returns
		 * the key and data pair, not just the key!
		 */
		key.data = &recno;
		key.size = sizeof(recno);
		if ((ret = dbcp->get(dbcp, &key, &data, DB_SET_RECNO)) != 0)
			goto get_err;

		/* Display the key and data. */
		show("k/d\t", &key, &data);

		/* Move the cursor a record forward. */
		if ((ret = dbcp->get(dbcp, &key, &data, DB_NEXT)) != 0)
			goto get_err;

		/* Display the key and data. */
		show("next\t", &key, &data);

		/*
		 * Retrieve the record number for the following record into
		 * local memory.
		 */
		data.data = &recno;
		data.size = sizeof(recno);
		data.ulen = sizeof(recno);
		data.flags |= DB_DBT_USERMEM;
		if ((ret = dbcp->get(dbcp, &key, &data, DB_GET_RECNO)) != 0) {
get_err:		dbp->err(dbp, ret, "DBcursor->get");
			if (ret != DB_NOTFOUND && ret != DB_KEYEMPTY)
				goto err2;
		} else
			printf("retrieved recno: %lu\n", (u_long)recno);

		/* Reset the data DBT. */
		memset(&data, 0, sizeof(data));
	}

	if ((ret = dbcp->close(dbcp)) != 0) {
		dbp->err(dbp, ret, "DBcursor->close");
		goto err1;
	}
	if ((ret = dbp->close(dbp, 0)) != 0) {
		fprintf(stderr,
		    "%s: DB->close: %s\n", progname, db_strerror(ret));
		return (1);
	}

	return (0);

err2:	(void)dbcp->close(dbcp);
err1:	(void)dbp->close(dbp, 0);
	return (ret);

}