📄 blob.c
字号:
/************************************************************
* *
* Copyright (c) 2001-2007 McObject LLC. All Right Reserved.*
* *
************************************************************/
/*
*
* This sample demostrates basic BLOB operations.
*
* Functions:
* write_blob() is called in the loop and attempts to write objects with
* blob fields a NumBlobs times. If the database doesn't have enough space allocated,
* the function fails with MCO_S_NOMEM. The total size is counted.
*
* read_blob() reads blob data out of the object found by its OID;the total
* size of all the data read and written to the database is counted;
* the write and read counters should be equal.
*
* The following runtime interfaces are used:
* MCO_RET BlobClass_new ( IN mco_trans_h t, IN const simple_OID *id, OUT BlobClass *handle );
* MCO_RET BlobClass_find_by_OID( IN mco_trans_h t, IN const simple_OID *id, OUT BlobClass *handle );
* MCO_RET BlobClass_OID_get ( IN BlobClass *handle, OUT simple_OID *id );
* MCO_RET BlobClass_blo_size ( IN BlobClass *handle, OUT uint4 * result);
* MCO_RET BlobClass_blo_put ( IN BlobClass *handle, IN const void * src, IN uint4 nbytes );
*/
#include "platform.h"
#include <stdio.h>
#include <stdlib.h>
#include "samples.h"
static const char* dbname = "SimpleDb";
static const int FIRST_SEGSZ = 1024 * 15000UL;
#ifndef MCO_PLATFORM_X64
static const int PAGESIZE = 96;
#else
static const int PAGESIZE = 192;
#endif
static const int NumBlobs = 1000;
static const int BlobSize = 100000;
const int MAP_ADDRESS = 0x20000000;
void _SH_(void)
{
char text[] =
{
"\nThis samples demonstartes basic eXtremeDB BLOB functions\n"
};
char text1[] =
{
"Copyright (c) 2001-2007 McObject LLC. All Right Reserved.\n\n"
};
printf("%s\neXtremeDB runtime version %d.%d, build %d\n%s\n\nPress Enter to start", text, MCO_COMP_VER_MAJOR,
MCO_COMP_VER_MINOR, MCO_COMP_BUILD_NUM, text1);
getchar();
}
void showMem(mco_db_h db)
{
mco_puint totalpg, freepg;
mco_db_free_pages(db, &freepg);
mco_db_total_pages(db, &totalpg);
printf("\n\tMemory Report:\n\ttotal pages=%d (%dK)\n\tfree pages=%d (%dK)\n\tused %dK\n", totalpg, totalpg*
PAGESIZE / 1024, freepg, freepg* PAGESIZE / 1024, (totalpg - freepg)* PAGESIZE / 1024);
}
static int update_blob(mco_db_h db, int objid)
{
MCO_RET rc;
int k, ret = 0;
simple_oid id;
BlobClass blob;
mco_trans_h t = 0;
char* buf = 0;
uint4 blob_size;
if (MCO_S_OK != (rc = mco_trans_start(db, MCO_READ_WRITE, MCO_TRANS_FOREGROUND, &t)))
{
printf("\nError (%d) starting transaction\n", rc);
goto end;
}
id.seq = objid;
if (MCO_S_OK != (rc = BlobClass_oid_find(t, &id, &blob)))
{
if (rc == MCO_S_NOTFOUND)
{
printf("\nError locating object (%d) - object not found\n", rc);
}
else
{
printf("\nError locating object (%d)\n", rc);
}
goto end;
}
if (rc = BlobClass_blo_size(&blob, &blob_size))
{
goto end;
}
if (!(buf = malloc(blob_size)))
{
goto end;
}
rc = BlobClass_blo_get(&blob, 0, buf, blob_size, 0);
for (k = 0; k < (int)blob_size; k++)
{
buf[k]++;
}
rc = BlobClass_blo_put(&blob, buf, blob_size);
end: if (t)
{
mco_trans_commit(t);
}
if (buf)
{
free(buf);
}
return rc;
}
static int read_blob(mco_db_h db, int objid, uint4* lgb)
{
MCO_RET rc;
int ret = 0, k;
simple_oid id;
BlobClass bo;
mco_trans_h t = 0;
char* buf = 0;
uint4 start = 0, retlen, bufsz = BlobSize;
if (MCO_S_OK != (rc = mco_trans_start(db, MCO_READ_ONLY, MCO_TRANS_FOREGROUND, &t)))
{
printf("\nError (%d) starting transaction\n", rc);
goto end;
}
id.seq = objid;
if (0 != (rc = BlobClass_oid_find(t, &id, &bo)))
{
if (rc == MCO_S_NOTFOUND)
{
printf("\nError locating object (%d) - object not found\n", rc);
}
else
{
printf("\nError locating object (%d)\n", rc);
}
ret = 0;
goto end;
}
rc = BlobClass_blo_size(&bo, lgb);
if (!(buf = malloc(BlobSize)))
{
goto end;
}
for (k = 0;; k++)
{
retlen = 0;
rc = BlobClass_blo_get(&bo, start, buf, 200, &retlen);
if (rc)
{
printf("\nError reading BLOB (%d)", rc);
ret = 0;
goto end;
}
if (retlen == 0)
{
break;
}
start += retlen;
}
ret = 1;
end: if (t)
{
mco_trans_commit(t);
}
if (buf)
{
free(buf);
}
return ret;
}
static short write_blob(mco_db_h db, int objid, const char* text, int lgtext, int* added)
{
mco_trans_h t = 0;
MCO_RET rc;
simple_oid id;
BlobClass bo;
id.seq = objid;
if (0 != (rc = mco_trans_start(db, MCO_READ_WRITE, MCO_TRANS_FOREGROUND, &t)))
{
printf("\nError starting transaction (%d)", rc);
exit(1);
}
rc = BlobClass_new(t, &id, &bo);
rc = BlobClass_blo_put(&bo, text, lgtext);
if (rc)
{
if (rc == MCO_E_NOMEM)
{
printf("\nError writing BLOB (%d) - out of memory", rc);
}
else
{
printf("\nError writing BLOB: %d", rc);
}
mco_trans_rollback(t);
return rc;
}
/* append the blob */
if (MCO_E_NOMEM == (rc = BlobClass_blo_append(&bo, "endofblob", * added = 9)))
{
printf("\nCouldn't append to BLOB (%d) - out of memory", rc);
mco_trans_rollback(t);
return rc;
}
rc = mco_trans_commit(t);
return rc;
}
/* fatal error handler */
static void errhandler(int n)
{
printf("\neXtremeDB runtime fatal error: %d", n);
getchar();
exit( - 1);
}
int main(void)
{
MCO_RET rc;
mco_db_h db = 0;
int objid = 1000;
int i, j;
time_t t1, t2;
uint4 tsize = 0, lgtxt;
char* txt = malloc(BlobSize);
char* start_mem;
mco_runtime_info_t info;
_SH_();
mco_get_runtime_info(&info);
if (info.mco_shm_supported)
{
start_mem = (char*)MAP_ADDRESS;
}
else
{
start_mem = (char*)malloc(FIRST_SEGSZ);
if (!start_mem)
{
printf("Couldn't allocated memory\n");
exit(1);
}
};
/* set fatal error handler */
mco_error_set_handler(&errhandler);
rc = mco_runtime_start();
/* Create the database named "SimpleDb" */
rc = mco_db_open(dbname, simple_get_dictionary(), start_mem, FIRST_SEGSZ, (uint2)PAGESIZE);
if (rc)
{
printf("\nerror creating database");
if (!info.mco_shm_supported)
{
free(start_mem);
}
exit(1);
}
/* the database is sucessfully created, connect to it and obtain a database handle */
mco_db_connect(dbname, &db);
printf("\ndb handle = %d\n", db);
showMem(db);
/* start the timer, write NumBlobs into the database */
time(&t1);
for (i = 0; i < NumBlobs; i++)
{
int added; // bytes appended inside write_blob, over lgtxt
objid++;
lgtxt = i + 40;
if (i > NumBlobs / 2)
{
lgtxt += 20000;
}
for (j = 0; j < (int)lgtxt; j++)
{
txt[j] = 'A' + (i % 5) + (j % 30);
}
if (MCO_S_OK != write_blob(db, objid, txt, lgtxt, &added))
{
break;
}
/* total size of BLOBs written */
tsize += lgtxt + added;
if (i % 20 == 0)
/* report only every 20, otherwise the screen get messy */
{
printf("\t\t%d blobs created\n", i);
}
}
showMem(db);
time(&t2);
if (tsize > 1024)
{
printf("\n\tTotal %ld K written for %d sec", tsize / 1024, (int)(t2 - t1));
}
else
{
printf("\n\tTotal %d bytes written for %d sec", tsize, (int)(t2 - t1));
}
objid = 1000;
lgtxt = tsize = 0;
/* read the data back */
time(&t1);
for (i = 0; i < NumBlobs; i++)
{
objid++;
if (!read_blob(db, objid, &lgtxt))
{
break;
}
/* total size of BLOB data read */
tsize += lgtxt;
}
time(&t2);
printf("\n\tTotal %ldK read for %d sec", tsize / 1024, (int)(t2 - t1));
/* update the blobs */
time(&t1);
tsize = 0;
objid = 1000;
for (i = 0; i < NumBlobs; i++)
{
objid++;
if (MCO_S_OK != update_blob(db, objid))
{
break;
}
}
time(&t2);
printf("\n\n\t%d blobs updated for %d sec", i, (int)(t2 - t1));
/* disconnect from the database, db is no longer valid */
mco_db_disconnect(db);
/* destroys the db instance */
mco_db_close(dbname);
mco_runtime_stop();
free(txt);
if (!info.mco_shm_supported)
{
free(start_mem);
}
printf("\n\npress Enter to finish\n");
getchar();
PROG_EXIT(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -