Skip to content

Commit 58d785a

Browse files
Fix race condition in nextInsertBatch() causing off-by-1 doc count
has_next_create() and next() were separate non-atomic operations, allowing two threads to both pass the boundary check at create_e and produce one extra document beyond the intended range. Fix: atomically claim the index with getAndIncrement() first, then break if the claimed index is out of bounds — eliminating the check-then-act gap. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 94ef7e5 commit 58d785a

1 file changed

Lines changed: 18 additions & 13 deletions

File tree

src/main/java/utils/docgen/DocumentGenerator.java

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -350,23 +350,26 @@ public WorkLoadSettings get_work_load_settings() {
350350
return this.ws;
351351
}
352352

353-
public Tuple2<String, Object> next() {
354-
long temp = this.ws.dr.createItr.getAndIncrement();
353+
private Tuple2<String, Object> nextCreateAt(long idx) {
355354
String k = null;
356355
Object v = null;
357-
try {
358-
if (this.target_vbuckets != null && this.target_vbuckets.length > 0) {
359-
k = this.generated_create_keys.get(temp);
360-
} else {
361-
k = (String) this.keyMethod.invoke(this.keys, temp);
362-
}
363-
v = (Object) this.valMethod.invoke(this.vals, k);
364-
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
365-
e1.printStackTrace();
356+
try {
357+
if (this.target_vbuckets != null && this.target_vbuckets.length > 0) {
358+
k = this.generated_create_keys.get(idx);
359+
} else {
360+
k = (String) this.keyMethod.invoke(this.keys, idx);
366361
}
362+
v = (Object) this.valMethod.invoke(this.vals, k);
363+
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
364+
e1.printStackTrace();
365+
}
367366
return Tuples.of(k, v);
368367
}
369368

369+
public Tuple2<String, Object> next() {
370+
return nextCreateAt(this.ws.dr.createItr.getAndIncrement());
371+
}
372+
370373
public Tuple2<String, Object> nextRead() {
371374
long temp = this.ws.dr.readItr.getAndIncrement();
372375
String k = null;
@@ -464,8 +467,10 @@ public Tuple2<String, Object> nextExpiry() {
464467
public List<Tuple2<String, Object>> nextInsertBatch() {
465468
List<Tuple2<String, Object>> docs = new ArrayList<Tuple2<String,Object>>();
466469
int count = 0;
467-
while (this.has_next_create() && count<ws.batchSize*ws.creates/100) {
468-
docs.add(this.next());
470+
while (count < ws.batchSize * ws.creates / 100) {
471+
long idx = this.ws.dr.createItr.getAndIncrement();
472+
if (idx >= this.ws.dr.create_e) break;
473+
docs.add(nextCreateAt(idx));
469474
count += 1;
470475
}
471476
return docs;

0 commit comments

Comments
 (0)