diff --git a/src/cmd.ts b/src/cmd.ts index a5c64e8..9ba8521 100644 --- a/src/cmd.ts +++ b/src/cmd.ts @@ -285,6 +285,21 @@ function matchingCommand(yargs: yargs.Argv<{}>): { type: "string", }, }) + .command("getCarsIdsWithState", "Get cars Ids and matching state", { + replicaIndex: { + description: "Replica index", + alias: "r", + demandOption: true, + type: "number", + }, + + path: { + description: "cars Ids file path", + alias: "p", + demandOption: true, + type: "string", + }, + }) .command("bidding", "Bidding matching", { matchingId: { description: "Matching Id", @@ -552,6 +567,8 @@ async function dataset( datasetId: Number(argv.datasetId), }) break + default: + console.log("Unknown command.") } } @@ -593,6 +610,13 @@ async function matching( path: String(argv.path), }) break + case "getCarsIdsWithState": + await new Matching().getCarsIdsWithState({ + context, + replicaIndex: Number(argv.replicaIndex), + path: String(argv.path), + }) + break case "bidding": await new Matching().bidding({ context, @@ -606,6 +630,8 @@ async function matching( matchingId: Number(argv.matchingId), }) break + default: + console.log("Unknown command.") } } @@ -665,6 +691,8 @@ async function storage( matchingId: Number(argv.matchingId), }) break + default: + console.log("Unknown command.") } } @@ -704,5 +732,7 @@ async function finance( }) ) break + default: + console.log("Unknown command.") } } diff --git a/src/matching/repo/index.ts b/src/matching/repo/index.ts index e5991f6..5f4ef9e 100644 --- a/src/matching/repo/index.ts +++ b/src/matching/repo/index.ts @@ -19,7 +19,7 @@ ********************************************************************************/ import fs from "fs" -import { MatchingState } from "@dataswapjs/dataswapjs" +import { MatchingState, Car } from "@dataswapjs/dataswapjs" import { handleEvmError, logMethodCall } from "../../shared/utils/utils" import { MatchingMetadataSubmitInfo, @@ -143,13 +143,50 @@ export class Matching { context: Context path: string }): Promise { - const ids = JSON.parse(fs.readFileSync(options.path).toString()) + const cars = JSON.parse(fs.readFileSync(options.path).toString()) return await handleEvmError( - options.context.evm.carstore.getCarsIds(ids.carsHash) + options.context.evm.carstore.getCarsIds(cars.carsHash) ) } + /** + * Retrieves the IDs of cars based on the provided JSON file path. + * + * @param options An object containing the context and the path to the JSON file. + * @returns A Promise resolving to an array of BigInt values representing the car IDs. + */ + @logMethodCall(["context"]) + async getCarsIdsWithState(options: { + context: Context + replicaIndex: number + path: string + }): Promise<{ matchinged: string[]; unmatching: string[] }> { + const cars = JSON.parse(fs.readFileSync(options.path).toString()) + + const ids: bigint[] = await handleEvmError( + options.context.evm.carstore.getCarsIds(cars.carsHash) + ) + const unmatching: bigint[] = [] + const matchinged: bigint[] = [] + + for (const id of ids) { + const car = (await handleEvmError( + options.context.evm.carstore.getCar(id) + )) as Car + + if ( + car.matchingIds && + car.matchingIds[options.replicaIndex] != (undefined || 0) + ) { + matchinged.push(id) + } else { + unmatching.push(id) + } + } + return await this.formatIdsWithState({ matchinged, unmatching }) + } + /** * Places a bid on a matching. * @param options - The options object containing the context, matching ID, and bid amount. @@ -189,4 +226,46 @@ export class Matching { ) ) } + + /** + * Formats the given IDs with their state (matchinged/unmatching). + * @param options The options object containing unmatching and matchinged IDs. + * @returns A Promise resolving to an object with formatted unmatching and matchinged IDs. + */ + private async formatIdsWithState(options: { + matchinged: bigint[] + unmatching: bigint[] + }): Promise<{ matchinged: string[]; unmatching: string[] }> { + const unmatchingIds: string[] = this.formatRange(options.unmatching) + const matchingedIds: string[] = this.formatRange(options.matchinged) + + return { matchinged: matchingedIds, unmatching: unmatchingIds } + } + + /** + * Formats the given array of IDs into ranges (e.g., [1, 2, 3, 5] => ["1-3", "5"]). + * @param ids The array of IDs to be formatted. + * @returns An array of strings representing formatted ranges of IDs. + */ + private formatRange(ids: bigint[]): string[] { + // Sort the IDs and remove duplicates + const sortedIds = Array.from(new Set(ids)).sort( + (a, b) => Number(a) - Number(b) + ) + const ranges: string[] = [] + + let start = sortedIds[0] + let end = sortedIds[0] + for (let i = 1; i < sortedIds.length; i++) { + if (sortedIds[i] - end === BigInt(1)) { + end = sortedIds[i] + } else { + ranges.push(start === end ? `${start}` : `${start}-${end}`) + start = end = sortedIds[i] + } + } + ranges.push(start === end ? `${start}` : `${start}-${end}`) + + return ranges + } }