// ============================================================================
// ==============================================================================
int main()
{
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    char szTmp[_MAX_STRING];
    std::map<__int64, std::string> mapOrgInfo;
    std::map<__int64, std::string> mapIndex;
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    printf("3DMotionOptTool ReduceVer %d\n", REDUCE_VERSION);
    printf("Drag a 3dmotion.ini file into this window:\n");
    gets(szTmp);
    ReadIndexFile(szTmp, mapOrgInfo);
    mapIndex = mapOrgInfo;
    {
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#ifdef CALC_REDUCE
        std::vector<FORMAT_RES_DATA> vecResData;
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        AnaResData(mapIndex, vecResData);
        printf("IndexSize %d ResSize %d\n", mapIndex.size(), vecResData.size());
#endif

        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        std::map<int, int> mapLookTrans;
        std::map<int, int> mapWeaponMotionTrans;
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        CalcTransTable(vecResData, mapLookTrans, mapWeaponMotionTrans);
        AdvanceReduce(mapOrgInfo, vecResData, mapIndex, mapLookTrans, mapWeaponMotionTrans);
        OutputSimpleReduceResult(mapIndex, mapLookTrans, mapWeaponMotionTrans);
    }

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    int nReduceVer;
    std::map<int, int> mapLookTrans;
    std::map<int, int> mapWeaponMotionTrans;
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    ReadReducedFile(pszTransFile, mapLookTrans, mapWeaponMotionTrans, nReduceVer);

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    std::map<__int64, std::string> mapNewIndex;
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    ReadIndexFile(pszNewMotionFile, mapNewIndex);

    Check(mapOrgInfo, mapNewIndex, mapLookTrans, mapWeaponMotionTrans, nReduceVer);

    while (getchar());
    return 0;
}
Exemple #2
0
static void IndexKVFile(const char* kvPath,
                        const char* backIndexPath,
                        const char* indexPath,
                        couchstore_json_reducer reducer)
{
    couchstore_error_t errcode;
    CouchStoreIndex* index = NULL;

    try(couchstore_create_index(indexPath, &index));
    try(couchstore_index_add(kvPath, COUCHSTORE_VIEW_PRIMARY_INDEX, reducer, index));
    try(couchstore_index_add(backIndexPath, COUCHSTORE_VIEW_BACK_INDEX, 0, index));
    try(couchstore_close_index(index));

cleanup:
    assert(errcode == 0);
}


static void ReadIndexFile(const char *indexPath)
{
    // See write_index_header in couch_index.c
    FILE *file = fopen(indexPath, "rb");
    fseek(file, 0, SEEK_END);
    long eof = ftell(file);
    long headerPos = eof - (eof % 4096);    // go to last 4KB boundary
    printf("Index header is at 0x%lx\n", headerPos);
    fseek(file, headerPos, SEEK_SET);

    // Header starts with a "1" byte, a length, and a CRC checksum:
    uint8_t flag;
    check_read(fread(&flag, 1, 1, file));
    assert_eq(flag, 1);
    uint32_t headerLength, headerChecksum;
    check_read(fread(&headerLength, sizeof(headerLength), 1, file));
    headerLength = ntohl(headerLength);
    check_read(fread(&headerChecksum, sizeof(headerChecksum), 1, file));
    headerChecksum = htonl(headerChecksum);
    assert_eq(headerPos + headerLength + 1 + 4, eof);

    // Next is the root count:
    uint32_t nRoots;
    check_read(fread(&nRoots, sizeof(nRoots), 1, file));
    nRoots = ntohl(nRoots);
    assert_eq(nRoots, 2);

    for (uint32_t root = 0; root < nRoots; ++root) {
        // The root has a type, size, node pointer, subtree size, and reduce data:
        uint8_t indexType; // really a couchstore_index_type
        check_read(fread(&indexType, 1, 1, file));
        assert_eq(indexType, root);  // i.e. first root is type 0, second is type 1
        uint16_t rootSize;
        check_read(fread(&rootSize, sizeof(rootSize), 1, file));
        rootSize = ntohs(rootSize);
        assert(rootSize >= 12);
        assert(rootSize < headerLength);
        uint64_t pointer = 0;
        uint64_t subtreesize = 0;
        check_read(fread((char*)&pointer + 2, 6, 1, file));
        check_read(fread((char*)&subtreesize + 2, 6, 1, file));
        pointer = ntohll(pointer);
        subtreesize = ntohll(subtreesize);
        sized_buf reduce = {NULL, rootSize - 12};
        reduce.buf = malloc(reduce.size);
        check_read(fread(reduce.buf, reduce.size, 1, file));

        printf("\tRoot: type=%d, pointer=%llu, subtreesize=%llu, reduce=%llu bytes\n",
               indexType, pointer, subtreesize, (uint64_t)reduce.size);
        assert((off_t)pointer < headerPos);
        assert((off_t)subtreesize < headerPos);

        // Examine the reduce values in the root node:
        assert(reduce.size >= 5 + 1024/8);
        uint64_t subtreeCount = 0;
        memcpy((uint8_t*)&subtreeCount + 3, reduce.buf, 5);
        subtreeCount = ntohll(subtreeCount);
        printf("\t      SubTreeCount = %llu\n", subtreeCount);
        assert_eq(subtreeCount, 1000);

        printf("\t      Bitmap = <");
        for (int i = 0; i < 128; ++i) {
            printf("%.02x", (uint8_t)reduce.buf[5 + i]);
            if (i % 4 == 3)
                printf(" ");
        }
        printf(">\n");
        
        if (indexType == COUCHSTORE_VIEW_PRIMARY_INDEX) {
            // JSON reductions:
            assert(reduce.size > 5 + 1024/8 + 2);
            char* jsonReduceStart = reduce.buf + 5 + 1024/8;
            sized_buf jsonReduce = {jsonReduceStart + 2, ntohs(*(uint16_t*)jsonReduceStart)};
            assert(jsonReduce.size < 1000);
            printf("\t      JSONReduction = '%.*s'\n", (int)jsonReduce.size, jsonReduce.buf);

            const char* expectedReduce = "{\"count\":1000,\"max\":99.51,\"min\":0.18,\"sum\":49547.93,\"sumsqr\":3272610.9289}";
            assert_eq(jsonReduce.size, strlen(expectedReduce));
            assert(strncmp(jsonReduce.buf, expectedReduce, strlen(expectedReduce)) == 0);
        }
    }
    
    assert_eq(ftell(file), eof);
    fclose(file);
}


void TestCouchIndexer(void) {
    fprintf(stderr, "Indexer: ");
    srandom(42);  // to get a consistent sequence of random numbers
    GenerateKVFile(KVPATH, 1000);
    srandom(42);  // to get a consistent sequence of random numbers
    GenerateBackIndexKVFile(KVBACKPATH, 1000);
    IndexKVFile(KVPATH, KVBACKPATH, INDEXPATH, COUCHSTORE_REDUCE_STATS);
    ReadIndexFile(INDEXPATH);
    unlink(KVPATH);
    unlink(INDEXPATH);
    fprintf(stderr, "OK\n");
}
// ============================================================================
// ==============================================================================
int main()
{
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	char szTmp[_MAX_STRING];
	std::map<__int64, std::string> mapOrgInfo;
	std::vector<NODE> vecOrder;
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	printf("WeaponMotion Reducer\n");
	printf("Drag a weaponMotion.ini file into this window:\n");
	gets(szTmp);
	ReadIndexFile(szTmp, vecOrder, mapOrgInfo);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	int nNewCount = 0;
	FILE *pFileOut = fopen(pszIniReduced, "w");
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	if (NULL == pFileOut) {
		ToolMsg("Create %s Failed", pszIniReduced);
		return 0;
	}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	std::map<__int64, std::string> mapReduceInfo;
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	std::vector<NODE>::const_iterator it(vecOrder.begin());
	for (; it != vecOrder.end(); ++it) {

		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		__int64 i64Index = it->i64Index;
		__int64 i64Mount = i64Index / WEAPON_MOTION_MOUNT_MUTI;
		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

		if (i64Mount > 1) {
			i64Index -= (i64Mount - 1) * WEAPON_MOTION_MOUNT_MUTI;
			if (mapOrgInfo[i64Index] != it->strRes) {
				ToolMsg("Error Index %I64d Res %s  !=  Reduce Index %I64d Res %s", it->i64Index, it->strRes.c_str(),
						i64Index, mapOrgInfo[i64Index].c_str());
				fprintf(pFileOut, "%s=%s\n", it->strIndex.c_str(), it->strRes.c_str());
				mapReduceInfo[it->i64Index] = it->strRes;
				++nNewCount;
			}

			continue;
		}

		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		__int64 i64Motion = i64Index % WEAPON_MOTION_LOOK_MUTI;
		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

		if (i64Motion != 9999) {

			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			__int64 i64Motion9999 = i64Index / WEAPON_MOTION_LOOK_MUTI * WEAPON_MOTION_LOOK_MUTI + 9999;
			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

			if (mapOrgInfo[i64Motion9999] == it->strRes) {
				continue;
			}
		}

		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		__int64 i64Look = i64Index % WEAPON_MOTION_WEAPON_MUTI / WEAPON_MOTION_LOOK_MUTI;
		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

		if (i64Look != 999) {

			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			__int64 i64Look999 = i64Index + (999 - i64Look) * WEAPON_MOTION_LOOK_MUTI;
			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

			if (mapOrgInfo[i64Look999] == it->strRes) {
				continue;
			}
		} else {

			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			__int64 i64WeaponQ = i64Index / WEAPON_MOTION_WEAPON_MUTI % 10;
			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

			if (i64WeaponQ) {

				//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
				__int64 i64IndexQ0 = i64Index - i64WeaponQ * WEAPON_MOTION_WEAPON_MUTI;
				//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

				if (mapOrgInfo[i64IndexQ0] == it->strRes) {
					continue;
				}
			}
		}

		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		__int64 i64LookMotion = i64Index % WEAPON_MOTION_WEAPON_MUTI;
		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

		if (i64LookMotion != 9999999) {

			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			__int64 i64LookMotion9999999 = i64Index / WEAPON_MOTION_WEAPON_MUTI * WEAPON_MOTION_WEAPON_MUTI + 9999999;
			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

			if (mapOrgInfo[i64LookMotion9999999] == it->strRes) {
				continue;
			}
		}

		if (i64Mount) {
			i64Index -= WEAPON_MOTION_MOUNT_MUTI;
			if (mapOrgInfo[i64Index] != it->strRes) {
				fprintf(pFileOut, "%s=%s\n", it->strIndex.c_str(), it->strRes.c_str());

				mapReduceInfo[it->i64Index] = it->strRes;
				++nNewCount;
			}

			continue;
		}

		fprintf(pFileOut, "%s=%s\n", it->strIndex.c_str(), it->strRes.c_str());
		mapReduceInfo[it->i64Index] = it->strRes;

		++nNewCount;
	}

	fclose(pFileOut);
	ToolMsg("Done. %d Index Save to %s", nNewCount, pszIniReduced);

	ToolMsg("Checking...");

	for (it = vecOrder.begin(); it != vecOrder.end(); ++it) {

		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		__int64 i64Index = it->i64Index;
		__int64 i64Mount = i64Index / WEAPON_MOTION_MOUNT_MUTI;
		__int64 i64ActType = i64Index % WEAPON_MOTION_LOOK_MUTI;
		__int64 id = i64Index % WEAPON_MOTION_MOUNT_MUTI - i64ActType;
		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

		if (i64Mount >= 1) {
			id += WEAPON_MOTION_MOUNT_MUTI;
		}

		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		__int64 idMotion = id + i64ActType;
		std::string strRes = mapReduceInfo[idMotion];
		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

		if (!strRes.empty()) {
			if (strRes != it->strRes) {
				ToolMsg("Error Index: %I64d  OrgRes: %s  Reduced Index: %I64d  ReduceRes: %s", it->i64Index,
						it->strRes.c_str(), idMotion, strRes.c_str());
				break;
			} else {
				continue;
			}
		}

		idMotion = id + 9999;
		strRes = mapReduceInfo[idMotion];
		if (!strRes.empty()) {
			if (strRes != it->strRes) {
				ToolMsg("Error Index: %I64d  OrgRes: %s  Reduced Index: %I64d  ReduceRes: %s", it->i64Index,
						it->strRes.c_str(), idMotion, strRes.c_str());
				break;
			} else {
				continue;
			}
		}

		idMotion = id -
			((id / WEAPON_MOTION_LOOK_MUTI) % 1000) *
			WEAPON_MOTION_LOOK_MUTI +
			999 *
			WEAPON_MOTION_LOOK_MUTI +
			i64ActType;
		strRes = mapReduceInfo[idMotion];
		if (!strRes.empty()) {
			if (strRes != it->strRes) {
				ToolMsg("Error Index: %I64d  OrgRes: %s  Reduced Index: %I64d  ReduceRes: %s", it->i64Index,
						it->strRes.c_str(), idMotion, strRes.c_str());
				break;
			} else {
				continue;
			}
		}

		idMotion = (id / WEAPON_MOTION_WEAPON_MUTI) * WEAPON_MOTION_WEAPON_MUTI + 9999999;
		strRes = mapReduceInfo[idMotion];
		if (!strRes.empty()) {
			if (strRes != it->strRes) {
				ToolMsg("Error Index: %I64d  OrgRes: %s  Reduced Index: %I64d  ReduceRes: %s", it->i64Index,
						it->strRes.c_str(), idMotion, strRes.c_str());
				break;
			} else {
				continue;
			}
		}

		idMotion = id -
			((id / WEAPON_MOTION_LOOK_MUTI) % WEAPON_MOTION_LOOK_MUTI) *
			WEAPON_MOTION_LOOK_MUTI +
			999 *
			WEAPON_MOTION_LOOK_MUTI +
			i64ActType;
		strRes = mapReduceInfo[idMotion];
		if (!strRes.empty()) {
			if (strRes != it->strRes) {
				ToolMsg("Error Index: %I64d  OrgRes: %s  Reduced Index: %I64d  ReduceRes: %s", it->i64Index,
						it->strRes.c_str(), idMotion, strRes.c_str());
				break;
			} else {
				continue;
			}
		}

		if (!i64Mount) {
			idMotion = 0;
			strRes = "";
			if (!it->strRes.empty()) {
				ToolMsg("Error Index: %I64d  OrgRes: %s  Reduced Index: %I64d  ReduceRes: %s", it->i64Index,
						it->strRes.c_str(), idMotion, strRes.c_str());
				break;
			} else {
				continue;
			}
		}

		id -= WEAPON_MOTION_MOUNT_MUTI;

		idMotion = id + i64ActType;
		strRes = mapReduceInfo[idMotion];
		if (!strRes.empty()) {
			if (strRes != it->strRes) {
				ToolMsg("Error Index: %I64d  OrgRes: %s  Reduced Index: %I64d  ReduceRes: %s", it->i64Index,
						it->strRes.c_str(), idMotion, strRes.c_str());
				break;
			} else {
				continue;
			}
		}

		idMotion = id + 9999;
		strRes = mapReduceInfo[idMotion];
		if (!strRes.empty()) {
			if (strRes != it->strRes) {
				ToolMsg("Error Index: %I64d  OrgRes: %s  Reduced Index: %I64d  ReduceRes: %s", it->i64Index,
						it->strRes.c_str(), idMotion, strRes.c_str());
				break;
			} else {
				continue;
			}
		}

		idMotion = id -
			((id / WEAPON_MOTION_LOOK_MUTI) % 1000) *
			WEAPON_MOTION_LOOK_MUTI +
			999 *
			WEAPON_MOTION_LOOK_MUTI +
			i64ActType;
		strRes = mapReduceInfo[idMotion];
		if (!strRes.empty()) {
			if (strRes != it->strRes) {
				ToolMsg("Error Index: %I64d  OrgRes: %s  Reduced Index: %I64d  ReduceRes: %s", it->i64Index,
						it->strRes.c_str(), idMotion, strRes.c_str());
				break;
			} else {
				continue;
			}
		}

		idMotion = (id / WEAPON_MOTION_WEAPON_MUTI) * WEAPON_MOTION_WEAPON_MUTI + 9999999;
		strRes = mapReduceInfo[idMotion];
		if (!strRes.empty()) {
			if (strRes != it->strRes) {
				ToolMsg("Error Index: %I64d  OrgRes: %s  Reduced Index: %I64d  ReduceRes: %s", it->i64Index,
						it->strRes.c_str(), idMotion, strRes.c_str());
				break;
			} else {
				continue;
			}
		}

		idMotion = id -
			((id / WEAPON_MOTION_LOOK_MUTI) % WEAPON_MOTION_LOOK_MUTI) *
			WEAPON_MOTION_LOOK_MUTI +
			999 *
			WEAPON_MOTION_LOOK_MUTI +
			i64ActType;
		strRes = mapReduceInfo[idMotion];
		if (!strRes.empty()) {
			if (strRes != it->strRes) {
				ToolMsg("Error Index: %I64d  OrgRes: %s  Reduced Index: %I64d  ReduceRes: %s", it->i64Index,
						it->strRes.c_str(), idMotion, strRes.c_str());
				break;
			} else {
				continue;
			}
		}

		if (!i64Mount) {
			idMotion = 0;
			strRes = "";
			if (!it->strRes.empty()) {
				ToolMsg("Error Index: %I64d  OrgRes: %s  Reduced Index: %I64d  ReduceRes: %s", it->i64Index,
						it->strRes.c_str(), idMotion, strRes.c_str());
				break;
			} else {
				continue;
			}
		}
	}

	if (it == vecOrder.end()) {
		ToolMsg("Checking Suc");
	} else {
		ToolMsg("Checking Failed");
	}

	while (getchar());

	return 0;
}