Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| SHA1 Hash: | f43bee2c1b00a1e8d974fa882a4cded941dd27b2 |
|---|---|
| Date: | 2012-11-28 19:39:14 |
| User: | dan |
| Comment: | Further updates to multi-threaded tests. |
Tags And Properties
- branch=trunk inherited from [84d5dea8fd]
- sym-trunk inherited from [84d5dea8fd]
Changes
Changes to lsm-test/lsmtest_tdb3.c
113 void *pWorkCtx; 113 void *pWorkCtx; 114 114 115 /* IO logging hook */ 115 /* IO logging hook */ 116 void (*xWriteHook)(void *, int, lsm_i64, int, int); 116 void (*xWriteHook)(void *, int, lsm_i64, int, int); 117 void *pWriteCtx; 117 void *pWriteCtx; 118 118 119 /* Worker threads (for lsm_mt) */ 119 /* Worker threads (for lsm_mt) */ > 120 int nMtMinCkpt; > 121 int nMtMaxCkpt; > 122 int eMode; 120 int nWorker; 123 int nWorker; 121 LsmWorker *aWorker; 124 LsmWorker *aWorker; 122 }; 125 }; > 126 > 127 #define LSMTEST_MODE_SINGLETHREAD 1 > 128 #define LSMTEST_MODE_BACKGROUND_CKPT 2 > 129 #define LSMTEST_MODE_BACKGROUND_WORK 3 > 130 #define LSMTEST_MODE_BACKGROUND_BOTH 4 123 131 124 /************************************************************************* 132 /************************************************************************* 125 ************************************************************************** 133 ************************************************************************** 126 ** Begin test VFS code. 134 ** Begin test VFS code. 127 */ 135 */ 128 136 129 struct LsmFile { 137 struct LsmFile { ................................................................................................................................................................................ 482 testFree(pDb->aFile[1].aSector); 490 testFree(pDb->aFile[1].aSector); 483 491 484 memset(pDb, sizeof(LsmDb), 0x11); 492 memset(pDb, sizeof(LsmDb), 0x11); 485 testFree((char *)pDb->pBuf); 493 testFree((char *)pDb->pBuf); 486 testFree((char *)pDb); 494 testFree((char *)pDb); 487 return rc; 495 return rc; 488 } 496 } 489 497 490 static int test_lsm_write( | 498 static int waitOnCheckpointer(LsmDb *pDb, lsm_db *db){ 491 TestDb *pTestDb, | 499 int nSleep = 0; 492 void *pKey, < 493 int nKey, | 500 int nByte; 494 void *pVal, < 495 int nVal | 501 int rc; 496 ){ < 497 LsmDb *pDb = (LsmDb *)pTestDb; < 498 502 > 503 do { 499 int nSleep = 0; | 504 nByte = 0; 500 while( pDb->aWorker && pDb->aWorker[0].bBlock ){ < > 505 rc = lsm_info(db, LSM_INFO_CHECKPOINT_SIZE, &nByte); > 506 if( rc!=LSM_OK || nByte<pDb->nMtMaxCkpt ) break; 501 usleep(1000); | 507 usleep(5000); 502 nSleep++; | 508 nSleep += 5; > 509 }while( 1 ); 503 } | 510 504 #if 0 511 #if 0 505 if( nSleep ) printf("nSleep=%d\n", nSleep); | 512 if( nSleep ) printf("waitOnCheckpointer(): nSleep=%d\n", nSleep); 506 if( pDb->aWorker ){ < > 513 #endif > 514 > 515 return rc; > 516 } > 517 > 518 static int waitOnWorker(LsmDb *pDb){ > 519 int rc; 507 int nLimit = -1; | 520 int nLimit = -1; 508 int nSleep = 0; | 521 int nSleep = 0; > 522 509 lsm_config(pDb->db, LSM_CONFIG_AUTOFLUSH, &nLimit); | 523 rc = lsm_config(pDb->db, LSM_CONFIG_AUTOFLUSH, &nLimit); 510 do { | 524 do { 511 int bOld, nNew, rc; | 525 int bOld, nNew, rc; 512 rc = lsm_info(pDb->db, LSM_INFO_TREE_SIZE, &bOld, &nNew); | 526 rc = lsm_info(pDb->db, LSM_INFO_TREE_SIZE, &bOld, &nNew); 513 if( rc!=LSM_OK ) return rc; | 527 if( rc!=LSM_OK ) return rc; 514 if( bOld==0 || nNew<nLimit ) break; | 528 if( bOld==0 || nNew<nLimit ) break; 515 usleep(1000); | 529 usleep(5000); 516 nSleep += 1; | 530 nSleep += 5; 517 }while( 1 ); | 531 }while( 1 ); > 532 518 #if 0 533 #if 0 519 if( nSleep ) printf("nSleep=%d\n", nSleep); | 534 if( nSleep ) printf("waitOnWorker(): nSleep=%d\n", nSleep); 520 #endif 535 #endif 521 } | 536 522 #endif < > 537 return rc; 523 | 538 } > 539 > 540 static int test_lsm_write( > 541 TestDb *pTestDb, > 542 void *pKey, > 543 int nKey, > 544 void *pVal, > 545 int nVal > 546 ){ > 547 LsmDb *pDb = (LsmDb *)pTestDb; > 548 int rc = LSM_OK; > 549 > 550 if( pDb->eMode==LSMTEST_MODE_BACKGROUND_CKPT ){ > 551 rc = waitOnCheckpointer(pDb, pDb->db); > 552 }else if( > 553 pDb->eMode==LSMTEST_MODE_BACKGROUND_WORK > 554 || pDb->eMode==LSMTEST_MODE_BACKGROUND_BOTH > 555 ){ > 556 rc = waitOnWorker(pDb); > 557 } > 558 > 559 if( rc==LSM_OK ){ 524 return lsm_insert(pDb->db, pKey, nKey, pVal, nVal); | 560 rc = lsm_insert(pDb->db, pKey, nKey, pVal, nVal); > 561 } > 562 return rc; 525 } 563 } 526 564 527 static int test_lsm_delete(TestDb *pTestDb, void *pKey, int nKey){ 565 static int test_lsm_delete(TestDb *pTestDb, void *pKey, int nKey){ 528 LsmDb *pDb = (LsmDb *)pTestDb; 566 LsmDb *pDb = (LsmDb *)pTestDb; 529 return lsm_delete(pDb->db, pKey, nKey); 567 return lsm_delete(pDb->db, pKey, nKey); 530 } 568 } 531 569 ................................................................................................................................................................................ 686 724 687 static void xWorkHook(lsm_db *db, void *pArg){ 725 static void xWorkHook(lsm_db *db, void *pArg){ 688 LsmDb *p = (LsmDb *)pArg; 726 LsmDb *p = (LsmDb *)pArg; 689 if( p->xWork ) p->xWork(db, p->pWorkCtx); 727 if( p->xWork ) p->xWork(db, p->pWorkCtx); 690 } 728 } 691 729 692 #define TEST_NO_RECOVERY -1 730 #define TEST_NO_RECOVERY -1 693 #define TEST_THREADS -2 < 694 #define TEST_COMPRESSION -3 731 #define TEST_COMPRESSION -3 > 732 > 733 #define TEST_MT_MODE -2 > 734 #define TEST_MT_MIN_CKPT -4 > 735 #define TEST_MT_MAX_CKPT -5 695 736 696 int test_lsm_config_str( 737 int test_lsm_config_str( 697 LsmDb *pLsm, 738 LsmDb *pLsm, 698 lsm_db *db, 739 lsm_db *db, 699 int bWorker, 740 int bWorker, 700 const char *zStr, 741 const char *zStr, 701 int *pnThread 742 int *pnThread ................................................................................................................................................................................ 715 { "mmap", 0, LSM_CONFIG_MMAP }, 756 { "mmap", 0, LSM_CONFIG_MMAP }, 716 { "use_log", 0, LSM_CONFIG_USE_LOG }, 757 { "use_log", 0, LSM_CONFIG_USE_LOG }, 717 { "automerge", 0, LSM_CONFIG_AUTOMERGE }, 758 { "automerge", 0, LSM_CONFIG_AUTOMERGE }, 718 { "max_freelist", 0, LSM_CONFIG_MAX_FREELIST }, 759 { "max_freelist", 0, LSM_CONFIG_MAX_FREELIST }, 719 { "multi_proc", 0, LSM_CONFIG_MULTIPLE_PROCESSES }, 760 { "multi_proc", 0, LSM_CONFIG_MULTIPLE_PROCESSES }, 720 { "worker_automerge", 1, LSM_CONFIG_AUTOMERGE }, 761 { "worker_automerge", 1, LSM_CONFIG_AUTOMERGE }, 721 { "test_no_recovery", 0, TEST_NO_RECOVERY }, 762 { "test_no_recovery", 0, TEST_NO_RECOVERY }, > 763 { "bg_min_ckpt", 0, TEST_NO_RECOVERY }, > 764 722 { "threads", 0, TEST_THREADS }, | 765 { "mt_mode", 0, TEST_MT_MODE }, > 766 { "mt_min_ckpt", 0, TEST_MT_MIN_CKPT }, > 767 { "mt_max_ckpt", 0, TEST_MT_MAX_CKPT }, > 768 723 #ifdef HAVE_ZLIB 769 #ifdef HAVE_ZLIB 724 { "compression", 0, TEST_COMPRESSION }, 770 { "compression", 0, TEST_COMPRESSION }, 725 #endif 771 #endif 726 { 0, 0 } 772 { 0, 0 } 727 }; 773 }; 728 const char *z = zStr; 774 const char *z = zStr; 729 int nThread = 1; 775 int nThread = 1; ................................................................................................................................................................................ 774 lsm_config(db, eParam, &iVal); 820 lsm_config(db, eParam, &iVal); 775 } 821 } 776 }else{ 822 }else{ 777 switch( eParam ){ 823 switch( eParam ){ 778 case TEST_NO_RECOVERY: 824 case TEST_NO_RECOVERY: 779 if( pLsm ) pLsm->bNoRecovery = iVal; 825 if( pLsm ) pLsm->bNoRecovery = iVal; 780 break; 826 break; 781 case TEST_THREADS: | 827 case TEST_MT_MODE: 782 if( pLsm ) nThread = iVal; 828 if( pLsm ) nThread = iVal; 783 break; 829 break; > 830 case TEST_MT_MIN_CKPT: > 831 if( pLsm && iVal>0 ) pLsm->nMtMinCkpt = iVal; > 832 break; > 833 case TEST_MT_MAX_CKPT: > 834 if( pLsm && iVal>0 ) pLsm->nMtMaxCkpt = iVal; > 835 break; 784 #ifdef HAVE_ZLIB 836 #ifdef HAVE_ZLIB 785 case TEST_COMPRESSION: 837 case TEST_COMPRESSION: 786 testConfigureCompression(db); 838 testConfigureCompression(db); 787 break; 839 break; 788 #endif 840 #endif 789 } 841 } 790 } 842 } 791 }else if( z!=zStart ){ 843 }else if( z!=zStart ){ 792 goto syntax_error; 844 goto syntax_error; 793 } 845 } 794 } 846 } 795 847 796 if( pnThread ) *pnThread = nThread; 848 if( pnThread ) *pnThread = nThread; > 849 if( pLsm && pLsm->nMtMaxCkpt < pLsm->nMtMinCkpt ){ > 850 pLsm->nMtMinCkpt = pLsm->nMtMaxCkpt; > 851 } > 852 797 return 0; 853 return 0; 798 syntax_error: 854 syntax_error: 799 testPrintError("syntax error at: \"%s\"\n", z); 855 testPrintError("syntax error at: \"%s\"\n", z); 800 return 1; 856 return 1; 801 } 857 } 802 858 803 int tdb_lsm_config_str(TestDb *pDb, const char *zStr){ 859 int tdb_lsm_config_str(TestDb *pDb, const char *zStr){ ................................................................................................................................................................................ 857 913 858 /* Default the sector size used for crash simulation to 512 bytes. 914 /* Default the sector size used for crash simulation to 512 bytes. 859 ** Todo: There should be an OS method to obtain this value - just as 915 ** Todo: There should be an OS method to obtain this value - just as 860 ** there is in SQLite. For now, LSM assumes that it is smaller than 916 ** there is in SQLite. For now, LSM assumes that it is smaller than 861 ** the page size (default 4KB). 917 ** the page size (default 4KB). 862 */ 918 */ 863 pDb->szSector = 256; 919 pDb->szSector = 256; > 920 > 921 /* Default values for the mt_min_ckpt and mt_max_ckpt parameters. */ > 922 pDb->nMtMinCkpt = 2 * (1<<20); > 923 pDb->nMtMaxCkpt = 16 * (1<<20); 864 924 865 memcpy(&pDb->env, tdb_lsm_env(), sizeof(lsm_env)); 925 memcpy(&pDb->env, tdb_lsm_env(), sizeof(lsm_env)); 866 pDb->env.pVfsCtx = (void *)pDb; 926 pDb->env.pVfsCtx = (void *)pDb; 867 pDb->env.xFullpath = testEnvFullpath; 927 pDb->env.xFullpath = testEnvFullpath; 868 pDb->env.xOpen = testEnvOpen; 928 pDb->env.xOpen = testEnvOpen; 869 pDb->env.xRead = testEnvRead; 929 pDb->env.xRead = testEnvRead; 870 pDb->env.xWrite = testEnvWrite; 930 pDb->env.xWrite = testEnvWrite; ................................................................................................................................................................................ 886 int nThread = 1; 946 int nThread = 1; 887 lsm_config_log(pDb->db, xLog, 0); 947 lsm_config_log(pDb->db, xLog, 0); 888 lsm_config_work_hook(pDb->db, xWorkHook, (void *)pDb); 948 lsm_config_work_hook(pDb->db, xWorkHook, (void *)pDb); 889 949 890 rc = test_lsm_config_str(pDb, pDb->db, 0, zCfg, &nThread); 950 rc = test_lsm_config_str(pDb, pDb->db, 0, zCfg, &nThread); 891 if( rc==LSM_OK ) rc = lsm_open(pDb->db, zFilename); 951 if( rc==LSM_OK ) rc = lsm_open(pDb->db, zFilename); 892 952 > 953 pDb->eMode = nThread; 893 #ifdef LSM_MUTEX_PTHREADS 954 #ifdef LSM_MUTEX_PTHREADS 894 if( rc==LSM_OK && nThread>1 ){ 955 if( rc==LSM_OK && nThread>1 ){ 895 testLsmStartWorkers(pDb, nThread, zFilename, zCfg); 956 testLsmStartWorkers(pDb, nThread, zFilename, zCfg); 896 } 957 } 897 #endif 958 #endif 898 959 899 if( rc!=LSM_OK ){ 960 if( rc!=LSM_OK ){ ................................................................................................................................................................................ 1052 1113 1053 pthread_mutex_lock(&p->worker_mutex); 1114 pthread_mutex_lock(&p->worker_mutex); 1054 while( (pWorker = p->pWorker) ){ 1115 while( (pWorker = p->pWorker) ){ 1055 int rc = LSM_OK; 1116 int rc = LSM_OK; 1056 int nCkpt = -1; 1117 int nCkpt = -1; 1057 1118 1058 /* Do some work. If an error occurs, exit. */ 1119 /* Do some work. If an error occurs, exit. */ 1059 pthread_mutex_unlock(&p->worker_mutex); < 1060 1120 > 1121 pthread_mutex_unlock(&p->worker_mutex); 1061 if( p->eType==LSMTEST_THREAD_CKPT ){ 1122 if( p->eType==LSMTEST_THREAD_CKPT ){ 1062 int nByte = 0; 1123 int nByte = 0; 1063 rc = lsm_info(pWorker, LSM_INFO_CHECKPOINT_SIZE, &nByte); 1124 rc = lsm_info(pWorker, LSM_INFO_CHECKPOINT_SIZE, &nByte); 1064 if( rc==LSM_OK && nByte>=(2*1024*1024) ){ | 1125 if( rc==LSM_OK && nByte>=p->pDb->nMtMinCkpt ){ 1065 if( nByte>(8*1024*1024) ) p->bBlock = 1; < 1066 rc = lsm_checkpoint(pWorker, 0); 1126 rc = lsm_checkpoint(pWorker, 0); 1067 p->bBlock = 0; < 1068 } 1127 } 1069 }else{ 1128 }else{ 1070 int nWrite = 0; /* Pages written by lsm_work() call */ < > 1129 int nWrite; > 1130 do { > 1131 1071 int nAuto = -1; /* Configured AUTOCHECKPOINT value */ | 1132 if( p->eType==LSMTEST_THREAD_WORKER ){ 1072 int nLimit = -1; /* Configured AUTOFLUSH value */ | 1133 waitOnCheckpointer(p->pDb, pWorker); 1073 | 1134 } 1074 lsm_config(pWorker, LSM_CONFIG_AUTOFLUSH, &nLimit); < 1075 lsm_config(pWorker, LSM_CONFIG_AUTOCHECKPOINT, &nAuto); < 1076 do { < 1077 lsm_info(pWorker, LSM_INFO_CHECKPOINT_SIZE, &nCkpt); < 1078 #if 0 < 1079 int nSleep = 0; < 1080 while( nAuto==0 && nCkpt>(nLimit*4) ){ < 1081 usleep(1000); < 1082 mt_signal_worker(p->pDb, 1); < 1083 nSleep++; < 1084 lsm_info(pWorker, LSM_INFO_CHECKPOINT_SIZE, &nCkpt); < 1085 } | 1135 1086 if( nSleep ) printf("nLimit=%d nSleep=%d (worker)\n", nLimit, nSleep); < 1087 #endif < > 1136 nWrite = 0; 1088 rc = lsm_work(pWorker, 0, 256, &nWrite); 1137 rc = lsm_work(pWorker, 0, 256, &nWrite); > 1138 1089 if( p->eType==LSMTEST_THREAD_WORKER_AC && nWrite && rc==LSM_OK ){ | 1139 if( p->eType==LSMTEST_THREAD_WORKER && nWrite ){ 1090 mt_signal_worker(p->pDb, 1); 1140 mt_signal_worker(p->pDb, 1); 1091 } 1141 } 1092 }while( nWrite && p->pWorker ); 1142 }while( nWrite && p->pWorker ); 1093 } 1143 } 1094 pthread_mutex_lock(&p->worker_mutex); 1144 pthread_mutex_lock(&p->worker_mutex); 1095 1145 1096 if( rc!=LSM_OK && rc!=LSM_BUSY ){ 1146 if( rc!=LSM_OK && rc!=LSM_BUSY ){ 1097 p->worker_rc = rc; 1147 p->worker_rc = rc; 1098 break; 1148 break; 1099 } 1149 } 1100 1150 1101 /* If the call to lsm_work() indicates that there is nothing more < 1102 ** to do at this point, wait on the condition variable. The thread will < 1103 ** wake up when it is signaled either because the client thread has | 1151 /* The thread will wake up when it is signaled either because another 1104 ** flushed an in-memory tree into the db file or when the connection < > 1152 ** thread has created some work for this one or because the connection 1105 ** is being closed. */ 1153 ** is being closed. */ 1106 if( p->pWorker && p->bDoWork==0 ){ 1154 if( p->pWorker && p->bDoWork==0 ){ 1107 pthread_cond_wait(&p->worker_cond, &p->worker_mutex); 1155 pthread_cond_wait(&p->worker_cond, &p->worker_mutex); 1108 } 1156 } 1109 p->bDoWork = 0; 1157 p->bDoWork = 0; 1110 } 1158 } 1111 pthread_mutex_unlock(&p->worker_mutex); 1159 pthread_mutex_unlock(&p->worker_mutex); ................................................................................................................................................................................ 1152 */ 1200 */ 1153 static void mt_client_work_hook(lsm_db *db, void *pArg){ 1201 static void mt_client_work_hook(lsm_db *db, void *pArg){ 1154 LsmDb *pDb = (LsmDb *)pArg; /* LsmDb database handle */ 1202 LsmDb *pDb = (LsmDb *)pArg; /* LsmDb database handle */ 1155 1203 1156 /* Invoke the user level work-hook, if any. */ 1204 /* Invoke the user level work-hook, if any. */ 1157 if( pDb->xWork ) pDb->xWork(db, pDb->pWorkCtx); 1205 if( pDb->xWork ) pDb->xWork(db, pDb->pWorkCtx); 1158 1206 1159 /* Signal the lsm_work() thread */ | 1207 /* Wake up worker thread 0. */ 1160 mt_signal_worker(pDb, 0); 1208 mt_signal_worker(pDb, 0); 1161 } 1209 } 1162 1210 1163 static void mt_worker_work_hook(lsm_db *db, void *pArg){ 1211 static void mt_worker_work_hook(lsm_db *db, void *pArg){ 1164 LsmDb *pDb = (LsmDb *)pArg; /* LsmDb database handle */ 1212 LsmDb *pDb = (LsmDb *)pArg; /* LsmDb database handle */ 1165 1213 1166 /* Invoke the user level work-hook, if any. */ 1214 /* Invoke the user level work-hook, if any. */ ................................................................................................................................................................................ 1198 if( rc==0 ) rc = lsm_open(p->pWorker, zFilename); 1246 if( rc==0 ) rc = lsm_open(p->pWorker, zFilename); 1199 lsm_config_log(p->pWorker, xLog, (void *)"worker"); 1247 lsm_config_log(p->pWorker, xLog, (void *)"worker"); 1200 1248 1201 /* Configure the work-hook */ 1249 /* Configure the work-hook */ 1202 if( rc==0 ){ 1250 if( rc==0 ){ 1203 lsm_config_work_hook(p->pWorker, mt_worker_work_hook, (void *)pDb); 1251 lsm_config_work_hook(p->pWorker, mt_worker_work_hook, (void *)pDb); 1204 } 1252 } > 1253 > 1254 if( eType==LSMTEST_THREAD_WORKER ){ > 1255 test_lsm_config_str(0, p->pWorker, 1, "autocheckpoint=0", 0); > 1256 } 1205 1257 1206 /* Kick off the worker thread. */ 1258 /* Kick off the worker thread. */ 1207 if( rc==0 ) rc = pthread_cond_init(&p->worker_cond, 0); 1259 if( rc==0 ) rc = pthread_cond_init(&p->worker_cond, 0); 1208 if( rc==0 ) rc = pthread_mutex_init(&p->worker_mutex, 0); 1260 if( rc==0 ) rc = pthread_mutex_init(&p->worker_mutex, 0); 1209 if( rc==0 ) rc = pthread_create(&p->worker_thread, 0, worker_main, (void *)p); 1261 if( rc==0 ) rc = pthread_create(&p->worker_thread, 0, worker_main, (void *)p); 1210 1262 1211 return rc; 1263 return rc; ................................................................................................................................................................................ 1226 1278 1227 /* Allocate space for two worker connections. They may not both be 1279 /* Allocate space for two worker connections. They may not both be 1228 ** used, but both are allocated. */ 1280 ** used, but both are allocated. */ 1229 pDb->aWorker = (LsmWorker *)testMalloc(sizeof(LsmWorker) * 2); 1281 pDb->aWorker = (LsmWorker *)testMalloc(sizeof(LsmWorker) * 2); 1230 memset(pDb->aWorker, 0, sizeof(LsmWorker) * 2); 1282 memset(pDb->aWorker, 0, sizeof(LsmWorker) * 2); 1231 1283 1232 switch( eModel ){ 1284 switch( eModel ){ 1233 case 2: | 1285 case LSMTEST_MODE_BACKGROUND_CKPT: 1234 pDb->nWorker = 1; 1286 pDb->nWorker = 1; 1235 test_lsm_config_str(0, pDb->db, 0, "autocheckpoint=0", 0); 1287 test_lsm_config_str(0, pDb->db, 0, "autocheckpoint=0", 0); 1236 rc = mt_start_worker(pDb, 0, zFilename, zCfg, LSMTEST_THREAD_CKPT); 1288 rc = mt_start_worker(pDb, 0, zFilename, zCfg, LSMTEST_THREAD_CKPT); 1237 break; 1289 break; 1238 1290 1239 case 3: | 1291 case LSMTEST_MODE_BACKGROUND_WORK: 1240 pDb->nWorker = 2; | 1292 pDb->nWorker = 1; 1241 assert( 0 ); | 1293 test_lsm_config_str(0, pDb->db, 0, "autowork=0", 0); > 1294 rc = mt_start_worker(pDb, 0, zFilename, zCfg, LSMTEST_THREAD_WORKER_AC); 1242 break; 1295 break; 1243 1296 1244 case 4: < > 1297 case LSMTEST_MODE_BACKGROUND_BOTH: 1245 pDb->nWorker = 2; 1298 pDb->nWorker = 2; 1246 assert( 0 ); < > 1299 test_lsm_config_str(0, pDb->db, 0, "autowork=0", 0); > 1300 rc = mt_start_worker(pDb, 0, zFilename, zCfg, LSMTEST_THREAD_WORKER); > 1301 if( rc==0 ){ > 1302 rc = mt_start_worker(pDb, 1, zFilename, zCfg, LSMTEST_THREAD_CKPT); > 1303 } 1247 break; 1304 break; 1248 } 1305 } 1249 1306 1250 return rc; 1307 return rc; 1251 } 1308 } 1252 1309 1253 1310 1254 int test_lsm_mt2(const char *zFilename, int bClear, TestDb **ppDb){ 1311 int test_lsm_mt2(const char *zFilename, int bClear, TestDb **ppDb){ 1255 const char *zCfg = "threads=2"; | 1312 const char *zCfg = "mt_mode=2"; 1256 return testLsmOpen(zCfg, zFilename, bClear, ppDb); 1313 return testLsmOpen(zCfg, zFilename, bClear, ppDb); 1257 } 1314 } 1258 1315 1259 int test_lsm_mt3(const char *zFilename, int bClear, TestDb **ppDb){ 1316 int test_lsm_mt3(const char *zFilename, int bClear, TestDb **ppDb){ 1260 const char *zCfg = "threads=3"; | 1317 const char *zCfg = "mt_mode=4"; 1261 return testLsmOpen(zCfg, zFilename, bClear, ppDb); 1318 return testLsmOpen(zCfg, zFilename, bClear, ppDb); 1262 } 1319 } 1263 1320 1264 #else 1321 #else 1265 static void mt_shutdown(LsmDb *pDb) { 1322 static void mt_shutdown(LsmDb *pDb) { 1266 unused_parameter(pDb); 1323 unused_parameter(pDb); 1267 } 1324 }
Changes to src/lsmInt.h
773 int lsmVarintLen32(int); 773 int lsmVarintLen32(int); 774 int lsmVarintSize(u8 c); 774 int lsmVarintSize(u8 c); 775 775 776 /* 776 /* 777 ** Functions from file "main.c". 777 ** Functions from file "main.c". 778 */ 778 */ 779 void lsmLogMessage(lsm_db *, int, const char *, ...); 779 void lsmLogMessage(lsm_db *, int, const char *, ...); > 780 int lsmInfoFreelist(lsm_db *pDb, char **pzOut); 780 781 781 /* 782 /* 782 ** Functions from file "lsm_log.c". 783 ** Functions from file "lsm_log.c". 783 */ 784 */ 784 int lsmLogBegin(lsm_db *pDb); 785 int lsmLogBegin(lsm_db *pDb); 785 int lsmLogWrite(lsm_db *, void *, int, void *, int); 786 int lsmLogWrite(lsm_db *, void *, int, void *, int); 786 int lsmLogCommit(lsm_db *); 787 int lsmLogCommit(lsm_db *);
Changes to src/lsm_main.c
421 421 422 static int infoFreelistCb(void *pCtx, int iBlk, i64 iSnapshot){ 422 static int infoFreelistCb(void *pCtx, int iBlk, i64 iSnapshot){ 423 LsmString *pStr = (LsmString *)pCtx; 423 LsmString *pStr = (LsmString *)pCtx; 424 lsmStringAppendf(pStr, "%s{%d %lld}", (pStr->n?" ":""), iBlk, iSnapshot); 424 lsmStringAppendf(pStr, "%s{%d %lld}", (pStr->n?" ":""), iBlk, iSnapshot); 425 return 0; 425 return 0; 426 } 426 } 427 427 428 static int infoFreelist(lsm_db *pDb, char **pzOut){ | 428 int lsmInfoFreelist(lsm_db *pDb, char **pzOut){ 429 Snapshot *pWorker; /* Worker snapshot */ 429 Snapshot *pWorker; /* Worker snapshot */ 430 int bUnlock = 0; 430 int bUnlock = 0; 431 LsmString s; 431 LsmString s; 432 int i; 432 int i; 433 int rc; 433 int rc; 434 434 435 /* Obtain the worker snapshot */ 435 /* Obtain the worker snapshot */ ................................................................................................................................................................................ 539 char **pzVal = va_arg(ap, char **); 539 char **pzVal = va_arg(ap, char **); 540 rc = lsmInfoLogStructure(pDb, pzVal); 540 rc = lsmInfoLogStructure(pDb, pzVal); 541 break; 541 break; 542 } 542 } 543 543 544 case LSM_INFO_FREELIST: { 544 case LSM_INFO_FREELIST: { 545 char **pzVal = va_arg(ap, char **); 545 char **pzVal = va_arg(ap, char **); 546 rc = infoFreelist(pDb, pzVal); | 546 rc = lsmInfoFreelist(pDb, pzVal); 547 break; 547 break; 548 } 548 } 549 549 550 case LSM_INFO_CHECKPOINT_SIZE: { 550 case LSM_INFO_CHECKPOINT_SIZE: { 551 int *pnByte = va_arg(ap, int *); 551 int *pnByte = va_arg(ap, int *); 552 rc = lsmCheckpointSize(pDb, pnByte); 552 rc = lsmCheckpointSize(pDb, pnByte); 553 break; 553 break;
Changes to src/lsm_shared.c
525 } 525 } 526 return 0; 526 return 0; 527 } 527 } 528 528 529 static int findFreeblock(lsm_db *pDb, i64 iInUse, int *piRet){ 529 static int findFreeblock(lsm_db *pDb, i64 iInUse, int *piRet){ 530 int rc; /* Return code */ 530 int rc; /* Return code */ 531 FindFreeblockCtx ctx; /* Context object */ 531 FindFreeblockCtx ctx; /* Context object */ > 532 > 533 #ifdef LSM_LOG_BLOCKS > 534 char *zList = 0; > 535 lsmInfoFreelist(pDb, &zList); > 536 lsmLogMessage(pDb, 0, > 537 "findFreeblock(): iInUse=%lld freelist=%s", iInUse, zList); > 538 lsmFree(pDb->pEnv, zList); > 539 #endif 532 540 533 ctx.iInUse = iInUse; 541 ctx.iInUse = iInUse; 534 ctx.iRet = 0; 542 ctx.iRet = 0; 535 rc = lsmWalkFreelist(pDb, findFreeblockCb, (void *)&ctx); 543 rc = lsmWalkFreelist(pDb, findFreeblockCb, (void *)&ctx); 536 *piRet = ctx.iRet; 544 *piRet = ctx.iRet; > 545 > 546 #ifdef LSM_LOG_BLOCKS > 547 lsmLogMessage(pDb, 0, "findFreeblock(): returning block %d", *piRet); > 548 #endif 537 return rc; 549 return rc; 538 } 550 } 539 551 540 /* 552 /* 541 ** Allocate a new database file block to write data to, either by extending 553 ** Allocate a new database file block to write data to, either by extending 542 ** the database file or by recycling a free-list entry. The worker snapshot 554 ** the database file or by recycling a free-list entry. The worker snapshot 543 ** must be held in order to call this function. 555 ** must be held in order to call this function. ................................................................................................................................................................................ 673 lsmFsMetaPageRelease(pPg); 685 lsmFsMetaPageRelease(pPg); 674 } 686 } 675 bDone = (iDisk>=iCkpt); 687 bDone = (iDisk>=iCkpt); 676 } 688 } 677 689 678 if( rc==LSM_OK && bDone==0 ){ 690 if( rc==LSM_OK && bDone==0 ){ 679 int iMeta = (pShm->iMetaPage % 2) + 1; 691 int iMeta = (pShm->iMetaPage % 2) + 1; 680 #if 0 < 681 lsmLogMessage(pDb, 0, "starting checkpoint"); < 682 #endif < 683 if( pDb->eSafety!=LSM_SAFETY_OFF ){ 692 if( pDb->eSafety!=LSM_SAFETY_OFF ){ 684 rc = lsmFsSyncDb(pDb->pFS); 693 rc = lsmFsSyncDb(pDb->pFS); 685 } 694 } 686 if( rc==LSM_OK ) rc = lsmCheckpointStore(pDb, iMeta); 695 if( rc==LSM_OK ) rc = lsmCheckpointStore(pDb, iMeta); 687 if( rc==LSM_OK && pDb->eSafety!=LSM_SAFETY_OFF){ 696 if( rc==LSM_OK && pDb->eSafety!=LSM_SAFETY_OFF){ 688 rc = lsmFsSyncDb(pDb->pFS); 697 rc = lsmFsSyncDb(pDb->pFS); 689 } 698 }
Changes to tool/lsmperf.tcl
186 append script $data3 186 append script $data3 187 append script $data4 187 append script $data4 188 188 189 append script "pause -1\n" 189 append script "pause -1\n" 190 exec_gnuplot_script $script $zPng 190 exec_gnuplot_script $script $zPng 191 } 191 } 192 192 193 do_write_test x.png 100 50000 0 20 { | 193 do_write_test x.png 60 50000 50000 200 { 194 lsm-mt "threads=2 multi_proc=0" | 194 lsm-mt "mt_mode=4 multi_proc=0 autoflush=4M" 195 leveldb leveldb 195 leveldb leveldb 196 } 196 } 197 197 198 198 199 #lsm "mmap=1 multi_proc=0 page_size=4096 block_size=2097152 autocheckpoint=419 199 #lsm "mmap=1 multi_proc=0 page_size=4096 block_size=2097152 autocheckpoint=419 200 #lsm-mt "mmap=1 multi_proc=0 threads=2 autowork=0 autocheckpoint=4196000" 200 #lsm-mt "mmap=1 multi_proc=0 threads=2 autowork=0 autocheckpoint=4196000" 201 201
Changes to tool/lsmview.tcl
361 361 362 362 363 proc static_redraw {C} { 363 proc static_redraw {C} { 364 link_varset $C myText myDb myData 364 link_varset $C myText myDb myData 365 $C delete all 365 $C delete all 366 draw_canvas_content $C $myData [list static_select_callback $C] 366 draw_canvas_content $C $myData [list static_select_callback $C] 367 } 367 } > 368 > 369 # The first parameter is the number of pages stored on each block of the > 370 # database file (i.e. if the page size is 4K and the block size 1M, 256). > 371 # The second parameter is a list of pages in a segment. > 372 # > 373 # The return value is a list of blocks occupied by the segment. > 374 # > 375 proc pagelist_to_blocklist {nBlkPg pglist} { > 376 set blklist [list] > 377 foreach pg $pglist { > 378 set blk [expr 1 + (($pg-1) / $nBlkPg)] > 379 if {[lindex $blklist end]!=$blk} { > 380 lappend blklist $blk > 381 } > 382 } > 383 set blklist > 384 } 368 385 369 proc static_select_callback {C segment} { 386 proc static_select_callback {C segment} { 370 link_varset $C myText myDb myData myTree myCfg 387 link_varset $C myText myDb myData myTree myCfg 371 foreach {iFirst iLast iRoot nSize $segment} $segment {} 388 foreach {iFirst iLast iRoot nSize $segment} $segment {} 372 389 373 set data [string trim [exec_lsmtest_show -c $myCfg $myDb array-pages $iFirst]] 390 set data [string trim [exec_lsmtest_show -c $myCfg $myDb array-pages $iFirst]] 374 $myText delete 0.0 end 391 $myText delete 0.0 end ................................................................................................................................................................................ 387 } { 404 } { 388 set nBlkPg $nBlksz 405 set nBlkPg $nBlksz 389 } else { 406 } else { 390 set nBlkPg [expr ($nBlksz / $nPgsz)] 407 set nBlkPg [expr ($nBlksz / $nPgsz)] 391 } 408 } 392 409 393 foreach pg $data { 410 foreach pg $data { 394 set blk [expr 1 + ($pg / $nBlkPg)] | 411 set blk [expr 1 + (($pg-1) / $nBlkPg)] 395 if {[info exists block($blk)]} { 412 if {[info exists block($blk)]} { 396 incr block($blk) 1 413 incr block($blk) 1 397 } else { 414 } else { 398 set block($blk) 1 415 set block($blk) 1 399 } 416 } 400 } 417 } 401 foreach blk [lsort -integer [array names block]] { | 418 foreach blk [pagelist_to_blocklist $nBlkPg $data] { 402 set nPg $block($blk) 419 set nPg $block($blk) 403 set blkid($blk) [$myTree insert {} end -text "block $blk ($nPg pages)"] 420 set blkid($blk) [$myTree insert {} end -text "block $blk ($nPg pages)"] 404 } 421 } 405 foreach pg $data { 422 foreach pg $data { 406 set blk [expr 1 + ($pg / $nBlkPg)] | 423 set blk [expr 1 + (($pg-1) / $nBlkPg)] 407 set id $blkid($blk) 424 set id $blkid($blk) 408 set item [$myTree insert $id end -text $pg] 425 set item [$myTree insert $id end -text $pg] 409 if {$pg == $iRoot} { 426 if {$pg == $iRoot} { 410 set rootitem $item 427 set rootitem $item 411 set rootparent $id 428 set rootparent $id 412 } 429 } 413 } 430 }