139 |
140 |
141 |
142 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 | [](https://gitlab.com/emc-mongoose/mongoose/commits/master)
3 | [](https://hub.docker.com/r/emcmongoose/mongoose/)
4 | [](https://gitter.im/emc-mongoose)
5 |
6 | # Mongoose Bundle
7 |
8 | The repo contains the automation scripts to build/test/deploy the Mongoose backward compatibility bundle. Previously the
9 | repo contained the Mongoose sources for the basic functionality and some commonly used extensions. Currently it was
10 | split into the independent repos and the corresponding components. Each component has its own documentation, CI versioning. For the
11 | mongoose documentation refer this [link](https://github.com/emc-mongoose/mongoose-base/tree/master/doc).
12 |
13 | # Bundle Contents
14 |
15 | The components listed below are included in this backward compatibility bundle.
16 |
17 | | Repo | Description | Latest Release | Integration Status | Issue Tracker Link |
18 | |------|-------------|---------|-------------------------------|--------|
19 | | [mongoose-**base**](https://github.com/emc-mongoose/mongoose-base) | Mongoose storage performance testing tool - base functionality |  |  | [BASE](https://mongoose-issues.atlassian.net/projects/BASE)
20 | | [mongoose-load-step-**pipeline**](https://github.com/emc-mongoose/mongoose-load-step-pipeline) | Load operations pipeline (create,delay,read-then-update, for example), extension |  |  | [BASE](https://mongoose-issues.atlassian.net/projects/BASE)
21 | | [mongoose-load-step-**weighted**](https://github.com/emc-mongoose/mongoose-load-step-weighted) | Weighted load extension, allowing to generate 20% write and 80% read operations, for example |  |  | [BASE](https://mongoose-issues.atlassian.net/projects/BASE)
22 | | [mongoose-storage-driver-**coop**](https://github.com/emc-mongoose/mongoose-storage-driver-coop) | Cooperative multitasking storage driver primitive, utilizing [fibers](https://github.com/akurilov/fiber4j) |  |  | [BASE](https://mongoose-issues.atlassian.net/projects/BASE)
23 | | [mongoose-storage-driver-**netty**](https://github.com/emc-mongoose/mongoose-storage-driver-netty) | [Netty](https://netty.io/)-storage-driver-nettyd storage driver primitive, extends the cooperative multitasking storage driver primitive |  |  | [BASE](https://mongoose-issues.atlassian.net/projects/BASE)
24 | | [mongoose-storage-driver-**nio**](https://github.com/emc-mongoose/mongoose-storage-driver-nio) | Non-blocking I/O storage driver primitive, extends the cooperative multitasking storage driver primitive |  |  | [BASE](https://mongoose-issues.atlassian.net/projects/BASE)
25 | | [mongoose-storage-driver-**http**](https://github.com/emc-mongoose/mongoose-storage-driver-http) | HTTP storage driver primitive, extends the Netty-storage-driver-httpd storage driver primitive |  |  | [BASE](https://mongoose-issues.atlassian.net/projects/BASE)
26 | | [mongoose-storage-driver-**fs**](https://github.com/emc-mongoose/mongoose-storage-driver-fs) | [VFS](https://www.oreilly.com/library/view/understanding-the-linux/0596005652/ch12s01.html) storage driver, extends the NIO storage driver primitive |  |  | [FS](https://mongoose-issues.atlassian.net/projects/FS)
27 | | [mongoose-storage-driver-**atmos**](https://github.com/emc-mongoose/mongoose-storage-driver-atmos) | [Dell EMC Atmos](https://poland.emc.com/collateral/software/data-sheet/h5770-atmos-ds.pdf) storage driver, extends the HTTP storage driver primitive |  |  | [BASE](https://mongoose-issues.atlassian.net/projects/BASE)
28 | | [mongoose-storage-driver-**s3**](https://github.com/emc-mongoose/mongoose-storage-driver-s3) | [Amazon S3](https://docs.aws.amazon.com/en_us/AmazonS3/latest/API/Welcome.html) storage driver, extends the HTTP storage driver primitive |  |  | [S3](https://mongoose-issues.atlassian.net/projects/S3)
29 | | [mongoose-storage-driver-**swift**](https://github.com/emc-mongoose/mongoose-storage-driver-swift) | [OpenStack Swift](https://wiki.openstack.org/wiki/Swift) storage driver, extends the HTTP storage driver primitive |  |  | [SWIFT](https://mongoose-issues.atlassian.net/projects/SWIFT)
30 |
31 | # Additional Extensions
32 |
33 | The *additional extension* are not included in this bundle.
34 |
35 | | Repo | Description | Latest Release | Integration Status | Issue Tracker Link |
36 | |------|-------------|---------|-------------------------------|--------|
37 | | [mongoose-storage-driver-**preempt**](https://github.com/emc-mongoose/mongoose-storage-driver-preempt) | Preemptive multitasking storage driver primitive, using thread-per-task approach for the I/O |  |  | [BASE](https://mongoose-issues.atlassian.net/projects/BASE)
38 | | [mongoose-storage-driver-**hdfs**](https://github.com/emc-mongoose/mongoose-storage-driver-hdfs) | [Apache HDFS](http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html) storage driver, extends the NIO storage driver primitive |  |  | [HDFS](https://mongoose-issues.atlassian.net/projects/HDFS)
39 | | [mongoose-storage-driver-**pravega**](https://github.com/emc-mongoose/mongoose-storage-driver-pravega) | [Pravega](http://pravega.io) storage driver, extends the preemptive multitasking storage driver primitive |  |  | [PRAVEGA](https://mongoose-issues.atlassian.net/projects/PRAVEGA)
40 | | [mongoose-storage-driver-**kafka**](https://github.com/emc-mongoose/mongoose-storage-driver-kafka) | [Apache Kafka](https://kafka.apache.org/) storage driver, extends the preemptive multitasking storage driver primitive |  |  | [KAFKA](https://mongoose-issues.atlassian.net/projects/KAFKA)
41 | | [mongoose-storage-driver-**pulsar**](https://github.com/emc-mongoose/mongoose-storage-driver-pulsar) | [Apache Pulsar](https://pulsar.apache.org/) storage driver, extends the cooperative multitasking storage driver primitive |  |  | [PULSAR](https://mongoose-issues.atlassian.net/projects/PULSAR)
42 |
43 | # Auxiliary Tools
44 |
45 | | Repo | Description | Latest Release | Integration Status | Issue Tracker Link |
46 | |------|-------------|---------|-------------------------------|--------|
47 | | [darzee](https://github.com/emc-mongoose/darzee) | Mongoose GUI web application | TBD | TBD | [GUI](https://mongoose-issues.atlassian.net/browse/GUI)
48 | | [mongoose-helm-charts](https://github.com/emc-mongoose/mongoose-helm-charts) | [Helm](https://helm.sh/) charts to easily deploy Mongoose in [K8s](https://kubernetes.io/) environment | TBD | TBD | [HELM](https://mongoose-issues.atlassian.net/projects/HELM/issues)
49 | | [e2e-latency-generator](https://github.com/emc-mongoose/e2e-latency-generator) | The tool consuming the Mongoose's operations trace output data and producing the raw end-to-end latency data and heatmap chart | - | - | -
50 | | [scenario-converter-3to4](https://github.com/emc-mongoose/scenario-converter-3to4) | This tool converts the Json-scenarios used in the Mongoose v3.* into new JavaScript-scenarios. | - | - | -
51 |
52 | # Backward Compatibility Notes
53 |
54 | * The extensions are not overriding the base default options when launched from the jar file. E.g. the default storage
55 | port is 7 and the default storage driver is "dummy-mock". Override the defaults explicitly or consider using the
56 | Docker image.
57 |
58 | * The base Mongoose version and this bundle version may differ. The base version is used to determine the logs output
59 | path.
60 |
61 | Example:
62 | ```bash
63 | java -jar mongoose-bundle-.jar \
64 | --storage-driver-type=s3 \
65 | --storage-net-node-port=9020
66 | ```
67 |
68 | # Build bundle
69 |
70 | ```bash
71 | ./gradlew clean jar
72 | ls -l build/libs
73 | ```
74 |
75 | # Deploy
76 |
77 | ## Bare Jar Download
78 |
79 | https://repo.maven.apache.org/maven2/com/github/emc-mongoose/mongoose-bundle/
80 |
81 | ## Docker
82 |
83 | ```bash
84 | docker run ... emcmongoose/mongoose[:] ...
85 | ```
86 |
87 | # Dependency
88 |
89 | The following dependency graph should be considered when running Mongoose w/o Docker and using some specific extension.
90 | For example, using the `mongoose-storage-driver-hdfs` extension will require to have the `mongoose-storage-driver-coop`
91 | and `mongoose-storage-driver-nio` extensions in the `~/.mongoose//ext` directory (with proper versions).
92 |
93 | ```
94 | mongoose-base
95 | |___ mongoose-load-step-pipeline
96 | |___ mongoose-load-step-weighted
97 | |___ mongoose-storage-driver-coop
98 | | |___ mongoose-storage-driver-netty
99 | | | |___ mongoose-storage-driver-http
100 | | | |___ mongoose-storage-driver-atmos
101 | | | |___ mongoose-storage-driver-s3
102 | | | |___ mongoose-storage-driver-swift
103 | | |___ mongoose-storage-driver-nio
104 | | | |___ mongoose-storage-driver-fs
105 | | | |___ mongoose-storage-driver-hdfs
106 | | |___ mongoose-storage-driver-pulsar
107 | |___ mongoose-storage-driver-preempt
108 | |___ mongoose-storage-driver-kafka
109 | |___ mongoose-storage-driver-pravega
110 | ```
111 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | Become one of the contributors! We thrive to build a welcoming and open community for anyone who wants to use Mongoose
2 | or contribute to it.
3 | [Here](https://github.com/thecodeteam/codedellemc.github.io/wiki/How-to-contribute-to-%7Bcode%7D-and-add-your-project)
4 | we describe how to contribute to any of the {code} projects.
5 |
6 | Please, note that all contributors shall follow the Contributor Agreement guidelines
7 | [provided here](https://github.com/thecodeteam/codedellemc.github.io/wiki/Contributor-Agreement).
8 |
9 | # Contents
10 |
11 | 1. [Contributors](#1-contributors)
12 | 1.2. [Roles](#12-roles)
13 | 2. [Versions](#2-versions)
14 | 2.1. [Backward Compatibility](#21-backward-compatibility)
15 | 2.2. [Numbers](#22-numbers)
16 | 3. [Issues](#3-issues)
17 | 3.1. [States](#31-states)
18 | 3.2. [Defects Priority](#32-defects-priority)
19 | 3.3. [Specific Properties](#33-specific-properties)
20 | 4. [Continuous Integration](#7-continuous-integration)
21 | 4.1. [Build](#41-build)
22 | 4.2. [Testing](#42-testing)
23 | 4.2.1. [Unit Tests](#421-unit-tests)
24 | 4.2.2. [Integration Tests](#422-integration-tests)
25 | 4.2.3. [Legacy System Tests](#423-system-tests)
26 | 4.2.3.1. [Containerized Tests](#4231-containerized-tests)
27 | 4.2.4. [Endurance Tests](#424-endurance-tests)
28 | 4.2.5. [Robot Tests](#425-robot-tests)
29 | 4.3. [Releasing](#43-releasing)
30 | 5. [Code](#6-code)
31 | 5.1. [Style](#51-style)
32 | 5.2. [Exception Handling](#52-exception-handling)
33 | 5.3. [Performance](#53-performance)
34 |
35 | # 1. Contributors
36 |
37 | Alphabetically:
38 |
39 | * [Andrey Kurilov](https://github.com/akurilov)
40 | * Gennady Eremeev
41 | * [Ilya Kisliakovsky](https://github.com/kisliakovsky)
42 | * [Kirill Gusakov](https://github.com/gusakk)
43 | * Mikhail Danilov
44 | * [Mikhail Malygin](https://github.com/aphreet)
45 | * [Olga Zhavzharova](https://github.com/Zhavzharova)
46 | * [Veronika Kochugova](https://github.com/veronikaKochugova)
47 |
48 | # 1.2. Roles
49 |
50 | | Name | Responsibilities | Current Assignees
51 | |------|------------------|------------------
52 | | User | Report the issues | Definitely unknown
53 | | Developer |
Development
Testing
Automation
Documentation
|
Veronika Kochugova
Andrey Kurilov
54 | | Owner |
The next version scope definition
Roadmap definition
User interaction
|
Andrey Kurilov
Veronika Kochugova
55 |
56 | # 2. Versions
57 |
58 | ## 2.1. Backward Compatibility
59 |
60 | The following interfaces are mentioned as the subject of the backward compatibility:
61 | 1. Input (item list files, scenario files, configuration options)
62 | 2. Output files containing the metrics
63 | 3. API
64 |
65 | ## 2.2. Numbers
66 |
67 | Mongoose uses the [semantic versioning](http://semver.org/). This means that the ***X.Y.Z*** version notation is used:
68 |
69 | * ***X***
70 | Major version number. Points to significant design and interfaces change. The *backward compatibility* is **not
71 | guaranteed**.
72 | * ***Y***
73 | Minor version number. The *backward compatibility* is guaranteed.
74 | * ***Z***
75 | Patch version number. Includes only the defect fixes.
76 |
77 | # 3. Issues
78 |
79 | Types:
80 | * Defect
81 | * Story
82 | * Task
83 | * Sub-task
84 |
85 | | Type | Description |
86 | |----------|-------------|
87 | | Defect | The defect/bug which **affects the released version** (the type "Task" should be used if a defect/bug affects the version which is not released yet) |
88 | | Story | High-level use case or a long-term activity aspect (testing, performance, etc) |
89 | | Task | A task which couldn't be included into any defect/story |
90 | | Sub-task | A task which could be included into a defect/story |
91 |
92 | Tracker link: https://mongoose-issues.atlassian.net/projects/GOOSE
93 |
94 | ## 3.1. States
95 |
96 | | State | Description |
97 | |-------------|-------------|
98 | | OPEN | All new issues should have this state. The issues are selected from the set of the *OPEN* issues for the proposal and review process. The task is updated w/ the corresponding comment but left in the *OPEN* state if it's considered incomplete/incorrect. Also incomplete/incorrect issue should be assigned back to the reporter.
99 | | PROPOSED | The issue is selected for the approval by the *owners*.
100 | | DEFERRED | Owners have approved the issue to be processed after the next major/minor (non-patch) version is released.
101 | | ACCEPTED | Owners approved the issue to be processed before the next major/minor (non-patch) version is released.
102 | | ESCALATED | Critical defect which interrupts all *DEFERRED*/*ACCEPTED* issues processing. Causes the new *patch* version release ASAP.
103 | | IN PROGRESS | The issue is in progress currently either initially done and the corresponding merge request to the `master` branch is created
104 | | RESOLVED | Issue is done and the corresponding changes are merged into the `master` branch
105 | | CLOSED | The new version is released containing the corresponding changes
106 |
107 | **Note**:
108 | > The corresponding impact probability/frequency is not taken into account in the process currently. For example, all
109 | > defects are assumed to be equally frequently occurring and affecting same users, regardless the particular
110 | > scenario/use case. This approach is used due to the lack of the sufficient statistical information about the Mongoose
111 | > usage.
112 |
113 | ## 3.2. Defects Priority
114 |
115 | | Priority | Conditions | Target state as a result of the review
116 | |--------------|------------|---------------------------------------
117 | | Critical | No workaround available **and** any of the following:
Crash
Hang
Not functioning
Functioning incorrectly
Performance degradation
| `ESCALATED`
118 | | Non-critical | Not *critical* **and** not *minor* | `ACCEPTED` (for the next minor/major version)
119 | | Minor | Any of the following:
Usability issue
Cosmetic
| `OPEN` or `ACCEPTED`
120 |
121 | ## 3.3. Specific properties
122 |
123 | | Name | Applicable Issue Types | Who is responsible to specify | Notes
124 | |-----------------------|------------------------|--------------------------------|-------|
125 | | Affected version | Defect | Reporter: user/developer/owner | Only the *latest* version may be used for the defect reporting. The issue should be *rejected* if the reported version is not *latest*.
126 | | Branch | Defect, Task, Sub-task | Reviewer: developer/owner |
127 | | Description | Task, Sub-task | Reporter: user/developer/owner |
128 | | Expected behaviour | Defect | Reporter: user/developer/owner | The reference to the particular documentation part describing the expected behavior is preferable.
129 | | Fix version | Defect, Task, Sub-task | Reviewer: developer/owner |
130 | | Limitations | Story | Reviewer: developer/owner |
131 | | Observed behaviour | Defect | Reporter: user/developer/owner | Error message, errors.log output file, etc.
132 | | Pull request | Defect, Task, Sub-task | Reviewer: developer/owner |
133 | | Resolution commit | Defect, Task, Sub-task | Reviewer: developer/owner |
134 | | Root cause | Defect | Reviewer: developer/owner |
135 | | Start command/request | Defect | Reporter: user/developer/owner | Leave only the essential things to reproduce: try to check if possible if the bug is reproducible w/o distributed mode, different concurrency level, item data size, etc.
136 | | Scenario | Defect | Reporter: user/developer/owner | Don't clutter with large scenario files. Simplify the scenario leaving only the essential things.
137 | | Steps | Defect | Reporter: user/developer/owner |
138 | | Purpose | Story | Reporter: user/developer/owner | Which particular problem should be solved with Mongoose? The links to the related documents and literature are encouraged.
139 | | Requirements | Story | Reporter: user/developer/owner | Both functional and performance requirements are mandatory. Optionally the additional requirements/possible enhancements may be specified.
140 |
141 | # 4. Continuous Integration
142 |
143 | https://gitlab.com/emcmongoose/mongoose/pipelines
144 | for Windows: https://ci.appveyor.com/project/veronikaKochugova/mongoose
145 |
146 | ## 4.1. Build
147 |
148 | Mongoose may be distributed as a single jar. JDK 11+ is required to build.
149 |
150 | ```bash
151 | ./gradlew clean jar
152 | ```
153 |
154 | The resulting jar file path is `./build/libs/mongoose-.jar`.
155 |
156 | ## 4.2. Testing
157 |
158 | ### 4.2.1. Unit Tests
159 |
160 | ```bash
161 | ./gradlew clean test
162 | ```
163 |
164 | ### 4.2.2. Integration Tests
165 |
166 | ```bash
167 | ./gradlew clean integrationTest
168 | ```
169 |
170 | ### 4.2.3. Legacy System Tests
171 |
172 | The system tests use the [JUnit parameterization](https://github.com/junit-team/junit4/wiki/Parameterized-tests). The parameter values are taken from the environment. The list of the system tests parameters below:
173 |
174 | | Parameter Name | Acceptable Values | Values Meaning
175 | |----------------|----------------------------------------|----------------
176 | | STORAGE_TYPE | s3, atmos, fs, swift | (the same)
177 | | RUN_MODE | local, distributed | 1, 2
178 | | CONCURRENCY | unlimited, single, small, medium, high | 0, 1, 10, 100, 1000
179 | | ITEM_SIZE | empty, small, medium, large, huge | 0, 10KB, 1MB, 100MB, 10GB
180 |
181 | To run the system tests for the particular case use the commands like
182 | below:
183 |
184 | ```bash
185 | export MONGOOSE_IMAGE_VERSION=testing
186 | export STORAGE_TYPE=s3
187 | export RUN_MODE=distributed
188 | export CONCURRENCY=medium
189 | export ITEM_SIZE=small
190 | ./gradlew clean systemTest --tests com.emc.mongoose.system.CircularAppendTest
191 | ```
192 |
193 | Note that some system tests will not run for some parameter values. The acceptable parameter values are declared explicitly in the `.travis.yml` file.
194 |
195 | #### 4.2.3.1. Containerized Tests
196 |
197 | Since v4.0.0 all system tests are containerized. To run a system test locally it's necessary to
198 | prepare testing Docker image manually:
199 |
200 | ```bash
201 | ./gradlew buildImage
202 | ```
203 |
204 | Also it's necessary to supply the testing image version to the system
205 | test via environment variable `MONGOOSE_IMAGE_VERSION`:
206 |
207 | ```bash
208 | export MONGOOSE_IMAGE_VERSION=testing
209 | export STORAGE_TYPE=atmos
210 | export RUN_MODE=distributed
211 | export CONCURRENCY=medium
212 | export ITEM_SIZE=small
213 | ./gradlew clean systemTest --tests com.emc.mongoose.system.CreateNoLimitTest
214 | ```
215 |
216 | ### 4.2.4. Endurance Tests
217 |
218 | ```bash
219 | export MONGOOSE_IMAGE_VERSION=testing
220 | export STORAGE_TYPE=swift
221 | export RUN_MODE=distributed
222 | export CONCURRENCY=unlimited
223 | export ITEM_SIZE=large
224 | ./gradlew clean enduranceTest --tests com.emc.mongoose.endurance.ParallelPipelineAndInfiniteLoopTest
225 | ```
226 |
227 | ### 4.2.5. Robot Tests
228 |
229 | *Note*:
230 | > Currently the Robot tests are failing when being executed locally and passing when being executed on the [Gitlab CI](https://gitlab.com/emcmongoose/mongoose/pipelines)
231 |
232 | ```bash
233 | export SUITE=
234 | export TEST=
235 | ./gradlew robotest
236 | ```
237 |
238 | Example:
239 | ```bash
240 | SUITE=api.storage TEST=s3 ./gradlew clean robotest
241 | ```
242 |
243 | ## 4.3. Releasing
244 |
245 | 1. Ensure all tests are OK
246 | 2. Ensure the new version documentation is ready
247 | 3. Share the testing build with QE and repeat this step until the qualification is OK
248 | 4. Create/replace the corresponding VCS tags:
249 | ```bash
250 | git tag -d latest
251 | git push origin :refs/tags/latest
252 | git tag -a .. -m ..
253 | git tag -a latest -m ..
254 | git push --tags --force
255 | ```
256 | 5. Create the corresponding version branch `release-v..` and set the version in the configuration to
257 | ..
258 | 6. Deploy docker images, set the `..` and `latest` tags also for the Docker images.
259 | 7. Upload the artifacts to the Central Maven repo:
260 | 1.
261 | ```bash
262 | ./gradlew clean uploadArchives
263 | ```
264 | 2. Go to the https://oss.sonatype.org/#stagingRepositories find the corresponding repository, close and then release
265 | it.
266 | 8. Update the projects depending on the Mongoose's API (storage drivers, at least)
267 |
268 | # 5. Code
269 |
270 | ## 5.1. Style
271 |
272 | [Google Java Style](https://google.github.io/styleguide/javaguide.html) is used as default.
273 |
274 | ### Autoformatting hook
275 |
276 | Git autoformatting hook reformats Java source code to comply with [Google Java Style](https://google.github.io/styleguide/javaguide.html).
277 |
278 | The hook script is in the root of the repository named `pre-commit`.`pre-commit` **MUST be copied to the directory** `.git/hooks/` and you need to check that the script has the access permissions to execute:
279 | ```bash
280 | ls -l pre-commit
281 | ```
282 | If not, assign permissions for execution:
283 | ```bash
284 | chmod +x pre-commit
285 | ```
286 | This hook will work automatically with any commit and format the code in the same style.
287 |
288 | ### In addition:
289 |
290 | * If interface is named `Foo` then:
291 | * Abstract implementation should be named as `FooBase`
292 | * Default concrete implementation should be names as `FooImpl`
293 | * Any field/local variable should be *final* if possible
294 |
295 | ## 5.2. Exception Handling
296 |
297 | The threads are not used in the usual way (*fibers* are used instead for the multitasking purposes). Therefore, having
298 | an `InterruptedException` thrown means that the run was interrupted externally. To stop the run, it's necessary to pass
299 | the exception to the uppermost level of the call stack. However, the `InterruptedException` is a checked
300 | exception and usually couldn't be passed outward. The utility method
301 | `com.github.akurilov.commons.lang.Exceptions#throwUnchecked` should be used for this:
302 |
303 | ```java
304 | ...
305 | import static com.github.akurilov.commons.lang.Exceptions.throwUnchecked;
306 | ...
307 | try {
308 | foo(); // may throw an InterruptedException
309 | } catch(final InterruptedException e) {
310 | throwUnchecked(e);
311 | }
312 | ```
313 |
314 | The following exceptions catching should be avoided as far as the `InterruptedException` may be swallowed occasionally:
315 | 1. `Throwable`
316 | 2. `Exception`
317 |
318 | ## 5.3. Performance
319 | Take care about the performance in the ***critical*** places:
320 | * Avoid *frequent* objects instantiation
321 | * Avoid unnecessary *frequent* allocation
322 | * Avoid *frequent* method calls if possible
323 | * Avoid deep call stack if possible
324 | * Avoid I/O threads blocking
325 | * Avoid anonymous classes in the time-critical code
326 | * Avoid non-static inner classes in the time-critical code
327 | * Use thread locals (encryption, string builders)
328 | * Use buffering, buffer everything
329 | * Use batch processing if possible
330 |
--------------------------------------------------------------------------------