This project is a console-based Java application designed to process collections of CS2 skin descriptions stored in JSON format and generate aggregated statistical reports in XML. The solution implements streaming JSON parsing, multithreaded file processing, and in-memory aggregation without using databases or frameworks such as Spring.
Represents an individual CS2 skin.
Attributes:
id – String
name – String
weapon – String
quality – String
exterior – String
floatValue – double
tags – String with multiple comma-separated values
The relationship is many-to-one: multiple skins reference a single weapon. Although represented as a simple string field, it logically forms: Weapon 1 → N Skins
[
{
"id": "1",
"name": "AK-47 | Custom Skin #1",
"weapon": "AK-47",
"quality": "Covert",
"exterior": "Field-Tested",
"floatValue": 0.654,
"tags": "meta, rifle, red"
},
{
"id": "2",
"name": "M4A1-S | Custom Skin #2",
"weapon": "M4A1-S",
"quality": "Restricted",
"exterior": "Factory New",
"floatValue": 0.123,
"tags": "popular, rifle, white"
}
]<statistics attribute="weapon">
<item>
<value>AK-47</value>
<count>59761</count>
</item>
<item>
<value>Desert Eagle</value>
<count>59550</count>
</item>
<item>
<value>USP-S</value>
<count>59495</count>
</item>
</statistics>The output file is named:
statistics_by_{attribute}.xml
mvn clean packagejava -jar target/ProfITsoftTask1-1.0-SNAPSHOT-jar-with-dependencies.jar <folder> <attribute> [threads]Where:
<folder>: directory containing JSON files<attribute>: one ofweapon,quality,exterior,tags...[threads]: optional number of threads (default: 1)
Example:
java -jar target/ProfITsoftTask1-1.0-SNAPSHOT-jar-with-dependencies.jar data weapon 4src/main/java
│
├── cli
│ └── Main.java // Console entry point
│
├── model
│ └── Skin.java // Domain entity
│
├── io
│ ├── JsonSkinFileParser.java // Streaming JSON parser
│ └── XmlStatisticsWriter.java // XML output writer
│
├── service
│ ├── StatisticsCalculator.java // Aggregation and sorting
│ └── SkinStatisticsService.java // Multithreaded file processing
│
└── util
└── SkinTestDataGenerator.java // Input data generator
Key characteristics:
- No database usage
- No Spring or frameworks
- In-memory aggregation using collections
- Jackson Streaming API ensures files are not fully loaded into memory
The assignment requires comparing performance for 1, 2, 4, and 8 threads. The dataset included:
- 50 files containing 5000 items each
- One file containing 100000 items
| Threads | Time (ms) |
|---|---|
| 1 | 186 |
| 2 | 191 |
| 4 | 188 |
| 8 | 183 |
- The dataset size is relatively small (~350,000 items total), and parsing is performed using a streaming parser.
- File system I/O and parser initialization dominate execution time.
- Thread overhead compensates for potential speedup, which is why execution times remain similar across different thread counts.
- For significantly larger datasets (tens or hundreds of megabytes), a noticeable improvement is expected at 2–4 threads.
The project includes unit tests covering:
Tests validate:
- correct extraction of skin attributes
- correct handling of multi-value tags
Tests validate:
- accumulation
- merging
- sorting in descending order
mvn testTests use small deterministic JSON files located in src/test/resources to ensure predictable and reproducible results.
The project satisfies the requirement to avoid loading entire JSON files into memory.
Parsing uses:
InputStream is = Files.newInputStream(path);
JsonParser parser = jsonFactory.createParser(is);This approach processes one skin object at a time, maintaining only aggregated statistics in memory.
The project implements all required features:
- Structured separation of responsibilities
- Support for multiple attributes including multi-valued fields
- Streaming JSON parsing
- Multithreaded processing with configurable thread count
- Sorted XML output file
- Unit tests covering core functionality
- Performance evaluation using different thread configurations
- Readme documentation including examples and analysis