Skip to content

Bump json from 20201115 to 20210307#9

Merged
lvca merged 1 commit into
mainfrom
dependabot/maven/org.json-json-20210307
Aug 31, 2021
Merged

Bump json from 20201115 to 20210307#9
lvca merged 1 commit into
mainfrom
dependabot/maven/org.json-json-20210307

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Aug 16, 2021

Copy link
Copy Markdown
Contributor

Bumps json from 20201115 to 20210307.

Release notes

Sourced from json's releases.

20210307

Pull Request Description
#575 Fix similar compare numbers
#577 Added clear() methods to JSONObject and JSONArray
#581 Use built-in Gradle shorthand notation for Maven Central repository
#583 Checked the length of key for checker framework
#588 JSONPointer should not process reverse solidus or double-quote chars in tokens

NOTE:

#588 is a potentially breaking change to JSONPointer. Embedded double quote and backslash chars are now handled differently (they are basically ignored by the JSONPointer parser). If this causes problems to your project, post an issue on the JSON-Java GitHub page.

Commits

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot merge will merge this PR after your CI passes on it
  • @dependabot squash and merge will squash and merge this PR after your CI passes on it
  • @dependabot cancel merge will cancel a previously requested merge and block automerging
  • @dependabot reopen will reopen this PR if it is closed
  • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Bumps [json](https://github.com/douglascrockford/JSON-java) from 20201115 to 20210307.
- [Release notes](https://github.com/douglascrockford/JSON-java/releases)
- [Commits](https://github.com/douglascrockford/JSON-java/commits)

---
updated-dependencies:
- dependency-name: org.json:json
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file java labels Aug 16, 2021
@lvca lvca merged commit 842b564 into main Aug 31, 2021
@dependabot dependabot Bot deleted the dependabot/maven/org.json-json-20210307 branch August 31, 2021 20:43
@lucian-cm lucian-cm mentioned this pull request Feb 13, 2023
lvca added a commit that referenced this pull request Jan 6, 2026
Fix for issue #3091 (Fix for Edge Index Corruption)

## Solution Summary

Implemented a general fix that **prevents RID reuse within the same transaction**, eliminating the root cause of index corruption.

## Root Cause

When an edge was deleted and its RID immediately reused within the same transaction with different property values, the index entries from the deleted record were not properly removed before the RID was assigned to a new record. This caused stale index entries pointing to the reused RID.

## The Fix

### 1. Track Deleted RIDs in Transaction Context
**File**: `engine/src/main/java/com/arcadedb/database/TransactionContext.java`

Added a `Set<RID>` to track all RIDs deleted in the current transaction:

```java
private final Set<RID> deletedRecordsInTx = new HashSet<>();

public void addDeletedRecord(final RID rid) {
  deletedRecordsInTx.add(rid);
}

public boolean isDeletedInTransaction(final RID rid) {
  return deletedRecordsInTx.contains(rid);
}
```

The set is cleared in the `reset()` method when the transaction commits or rolls back.

### 2. Mark RIDs as Deleted
**File**: `engine/src/main/java/com/arcadedb/engine/LocalBucket.java:line 1007`

When a record is deleted, add its RID to the transaction's deleted set:

```java
// POINTER = 0 MEANS DELETED
page.writeUnsignedInt(PAGE_RECORD_TABLE_OFFSET + positionInPage * INT_SERIALIZED_SIZE, 0);

// Track deleted RID to prevent reuse within the same transaction
database.getTransaction().addDeletedRecord(rid);
```

### 3. Prevent Reuse During Allocation
**File**: `engine/src/main/java/com/arcadedb/engine/LocalBucket.java:line 1588-1597`

Modified the `getFreeSpaceInPage()` method to skip RIDs deleted in the current transaction:

```java
for (int i = 0; i < pageAnalysis.totalRecordsInPage; i++) {
  final int recordPositionInPage = getRecordPositionInPage(pageAnalysis.page, i);
  if (recordPositionInPage == 0) {
    // Check if this position was deleted in the current transaction
    final RID potentialRID = new RID(database, file.getFileId(),
        ((long) pageAnalysis.page.getPageId().getPageNumber()) * maxRecordsInPage + i);

    if (!database.getTransaction().isDeletedInTransaction(potentialRID)) {
      // REUSE THE FIRST AVAILABLE POSITION FROM DELETED RECORD (from previous transactions only)
      if (pageAnalysis.availablePositionIndex == -1)
        pageAnalysis.availablePositionIndex = i;
    }
  } else if (recordPositionInPage > pageAnalysis.lastRecordPositionInPage)
    pageAnalysis.lastRecordPositionInPage = recordPositionInPage;
}
```

### 4. Supporting Fixes

**File**: `engine/src/main/java/com/arcadedb/database/DocumentIndexer.java:line 416`
- Moved `unsetDirty()` call to AFTER property extraction for index deletion

**File**: `engine/src/main/java/com/arcadedb/database/LocalDatabase.java:line 1031`
- Added handling to load full edge when deleting a `LightEdge` (which returns null for all properties)

## Benefits of This Approach

1. **General Solution**: Prevents RID reuse within ANY transaction, not just for edges
2. **Prevents Multiple Issues**: Eliminates a whole class of potential bugs related to RID reuse
3. **Simple and Clean**: Minimal code changes, easy to understand and maintain
4. **No Performance Impact**: HashSet lookup is O(1), and the set is cleared on transaction completion
5. **Cleaner Transaction Semantics**: RIDs allocated in a transaction remain stable until commit

## Test Results

The test case `EdgeIndexCorruptionTest` now passes:

**Before Fix:**
```
After Transaction #3:
- Edge #9:0: from_id=trs_2 (REUSED RID!)
- Edge #9:1: from_id=trs_1

Query for from_id='trs_1' returned 2 edges (WRONG - stale index entry for #9:0)
```

**After Fix:**
```
After Transaction #3:
- Edge #9:1: from_id=trs_2
- Edge #9:2: from_id=trs_1 (RID #9:0 NOT reused!)

Query for from_id='trs_1' returned 1 edge (CORRECT!)
```

## Files Modified

1. **engine/src/main/java/com/arcadedb/database/TransactionContext.java**
   - Added `deletedRecordsInTx` Set
   - Added `addDeletedRecord()` and `isDeletedInTransaction()` methods
   - Clear deleted set in `reset()` method

2. **engine/src/main/java/com/arcadedb/engine/LocalBucket.java**
   - Call `addDeletedRecord()` when record is deleted
   - Check `isDeletedInTransaction()` before reusing RID in `getFreeSpaceInPage()`

3. **engine/src/main/java/com/arcadedb/database/DocumentIndexer.java**
   - Moved `unsetDirty()` to after property extraction

4. **engine/src/main/java/com/arcadedb/database/LocalDatabase.java**
   - Added `LightEdge` import
   - Handle `LightEdge` by loading full edge before index deletion

5. **engine/src/test/java/com/arcadedb/graph/EdgeIndexCorruptionTest.java**
   - New test case that reproduces and validates the fix

## Backward Compatibility

This fix is **fully backward compatible**:
- No API changes
- No schema changes
- No data migration required
- Existing databases work without modification

## Performance Considerations

- **Memory**: O(N) where N is the number of deletions in a transaction (typically small)
- **CPU**: O(1) HashSet operations for add/check
- **Cleanup**: Automatic on transaction commit/rollback

The performance impact is negligible as:
1. Most transactions don't delete many records
2. HashSet operations are very fast
3. The set is cleared after each transaction

## Future Enhancements

This fix could be extended to:
1. Track all RID allocations in the transaction for rollback purposes
2. Provide transaction-level RID allocation statistics
3. Detect and warn about high RID churn within transactions
robfrank pushed a commit that referenced this pull request Feb 11, 2026
Fix for issue #3091 (Fix for Edge Index Corruption)

## Solution Summary

Implemented a general fix that **prevents RID reuse within the same transaction**, eliminating the root cause of index corruption.

## Root Cause

When an edge was deleted and its RID immediately reused within the same transaction with different property values, the index entries from the deleted record were not properly removed before the RID was assigned to a new record. This caused stale index entries pointing to the reused RID.

## The Fix

### 1. Track Deleted RIDs in Transaction Context
**File**: `engine/src/main/java/com/arcadedb/database/TransactionContext.java`

Added a `Set<RID>` to track all RIDs deleted in the current transaction:

```java
private final Set<RID> deletedRecordsInTx = new HashSet<>();

public void addDeletedRecord(final RID rid) {
  deletedRecordsInTx.add(rid);
}

public boolean isDeletedInTransaction(final RID rid) {
  return deletedRecordsInTx.contains(rid);
}
```

The set is cleared in the `reset()` method when the transaction commits or rolls back.

### 2. Mark RIDs as Deleted
**File**: `engine/src/main/java/com/arcadedb/engine/LocalBucket.java:line 1007`

When a record is deleted, add its RID to the transaction's deleted set:

```java
// POINTER = 0 MEANS DELETED
page.writeUnsignedInt(PAGE_RECORD_TABLE_OFFSET + positionInPage * INT_SERIALIZED_SIZE, 0);

// Track deleted RID to prevent reuse within the same transaction
database.getTransaction().addDeletedRecord(rid);
```

### 3. Prevent Reuse During Allocation
**File**: `engine/src/main/java/com/arcadedb/engine/LocalBucket.java:line 1588-1597`

Modified the `getFreeSpaceInPage()` method to skip RIDs deleted in the current transaction:

```java
for (int i = 0; i < pageAnalysis.totalRecordsInPage; i++) {
  final int recordPositionInPage = getRecordPositionInPage(pageAnalysis.page, i);
  if (recordPositionInPage == 0) {
    // Check if this position was deleted in the current transaction
    final RID potentialRID = new RID(database, file.getFileId(),
        ((long) pageAnalysis.page.getPageId().getPageNumber()) * maxRecordsInPage + i);

    if (!database.getTransaction().isDeletedInTransaction(potentialRID)) {
      // REUSE THE FIRST AVAILABLE POSITION FROM DELETED RECORD (from previous transactions only)
      if (pageAnalysis.availablePositionIndex == -1)
        pageAnalysis.availablePositionIndex = i;
    }
  } else if (recordPositionInPage > pageAnalysis.lastRecordPositionInPage)
    pageAnalysis.lastRecordPositionInPage = recordPositionInPage;
}
```

### 4. Supporting Fixes

**File**: `engine/src/main/java/com/arcadedb/database/DocumentIndexer.java:line 416`
- Moved `unsetDirty()` call to AFTER property extraction for index deletion

**File**: `engine/src/main/java/com/arcadedb/database/LocalDatabase.java:line 1031`
- Added handling to load full edge when deleting a `LightEdge` (which returns null for all properties)

## Benefits of This Approach

1. **General Solution**: Prevents RID reuse within ANY transaction, not just for edges
2. **Prevents Multiple Issues**: Eliminates a whole class of potential bugs related to RID reuse
3. **Simple and Clean**: Minimal code changes, easy to understand and maintain
4. **No Performance Impact**: HashSet lookup is O(1), and the set is cleared on transaction completion
5. **Cleaner Transaction Semantics**: RIDs allocated in a transaction remain stable until commit

## Test Results

The test case `EdgeIndexCorruptionTest` now passes:

**Before Fix:**
```
After Transaction #3:
- Edge #9:0: from_id=trs_2 (REUSED RID!)
- Edge #9:1: from_id=trs_1

Query for from_id='trs_1' returned 2 edges (WRONG - stale index entry for #9:0)
```

**After Fix:**
```
After Transaction #3:
- Edge #9:1: from_id=trs_2
- Edge #9:2: from_id=trs_1 (RID #9:0 NOT reused!)

Query for from_id='trs_1' returned 1 edge (CORRECT!)
```

## Files Modified

1. **engine/src/main/java/com/arcadedb/database/TransactionContext.java**
   - Added `deletedRecordsInTx` Set
   - Added `addDeletedRecord()` and `isDeletedInTransaction()` methods
   - Clear deleted set in `reset()` method

2. **engine/src/main/java/com/arcadedb/engine/LocalBucket.java**
   - Call `addDeletedRecord()` when record is deleted
   - Check `isDeletedInTransaction()` before reusing RID in `getFreeSpaceInPage()`

3. **engine/src/main/java/com/arcadedb/database/DocumentIndexer.java**
   - Moved `unsetDirty()` to after property extraction

4. **engine/src/main/java/com/arcadedb/database/LocalDatabase.java**
   - Added `LightEdge` import
   - Handle `LightEdge` by loading full edge before index deletion

5. **engine/src/test/java/com/arcadedb/graph/EdgeIndexCorruptionTest.java**
   - New test case that reproduces and validates the fix

## Backward Compatibility

This fix is **fully backward compatible**:
- No API changes
- No schema changes
- No data migration required
- Existing databases work without modification

## Performance Considerations

- **Memory**: O(N) where N is the number of deletions in a transaction (typically small)
- **CPU**: O(1) HashSet operations for add/check
- **Cleanup**: Automatic on transaction commit/rollback

The performance impact is negligible as:
1. Most transactions don't delete many records
2. HashSet operations are very fast
3. The set is cleared after each transaction

## Future Enhancements

This fix could be extended to:
1. Track all RID allocations in the transaction for rollback purposes
2. Provide transaction-level RID allocation statistics
3. Detect and warn about high RID churn within transactions

(cherry picked from commit a81163a)
This was referenced Feb 17, 2026
@claude claude Bot mentioned this pull request May 5, 2026
2 tasks
lvca added a commit that referenced this pull request Jun 17, 2026
…nput, MATLAB_COLUMN (#4642)

* feat: [#3099] vector quantization ergonomics, asSparse(), RRF array input, MATLAB_COLUMN

Follow-up to #3099 addressing the remaining actionable review items.

int8 quantization ergonomics (#8/#9/#10/#11):
- vectorDequantizeInt8 accepts the result of vectorQuantizeInt8() directly
  (single-arg form), so min/max no longer have to be unpacked by hand. The
  (bytes, min, max) form still works.
- vectorApproxDistance infers INT8 vs BINARY from the result objects, making
  the type string optional. Raw byte arrays still require an explicit type.
- "ranking preserved" reworded to "preserves the top-k ordering".

asSparse() method (#4): the method form of vector.denseToSparse(), consistent
with the asString()/asVector() conversion-method family. Delegates to the
function so the dense->sparse logic stays in one place.

RRF array input (#14): vectorRRFScore also accepts the ranks grouped in a
single array/list (plus optional { k }), consistent with vector.multiScore.

MATLAB_COLUMN format (#21): semicolon-separated column vector [1.0; 2.0; 3.0]
for vector.toString()/asString(). The asVector()/string parser now also splits
on semicolons so it round-trips.

Adds coverage in SQLFunctionVectorEnhancementsTest.

* fix: [#3099] address PR review - approxDistance mixed-type, RRF rank validation, asSparse singleton

- vectorApproxDistance.inferType: detect mixed INT8/BINARY result objects and throw a clear
  "Cannot mix INT8 and BINARY quantization results" error instead of routing to the wrong
  distance and surfacing a misleading "Expected BinaryQuantizationResult" message.
- vectorRRFScore: unify the variadic and array forms so both skip null ranks (item absent from
  that ranking list) and validate every present rank as a positive integer. The array form no
  longer accepts fractional ranks, and the variadic form no longer silently truncates them.
- SQLMethodAsSparse: reuse a shared stateless SQLFunctionVectorDenseToSparse instance instead of
  allocating one per call.
- SQLFunctionVectorDequantizeInt8.getSyntax(): disambiguate the two overloads.

Adds tests for mixed-type inference, null-rank parity, and non-integer rank rejection.

* fix: [#3099] address 2nd PR review - approxDistance inference guard, docs, test coverage

- vectorApproxDistance.inferType now requires BOTH 2-arg arguments to be quantization result objects;
  mixing a result object with a raw array (which inference can't do reliably) is rejected with a clear
  message pointing at the explicit 3-arg form.
- Clarify in the class Javadoc that BINARY requires the BinaryQuantizationResult (raw packed bits are not
  enough), while INT8 accepts a result or a raw byte array.
- Tidy getSyntax() of vectorDequantizeInt8 (drop the repeated function name).
- Tests: add non-zero distance assertions for both INT8 and BINARY inference, the 3-arg explicit form with
  result objects, and the result-object/raw-array mismatch rejection.

* fix: [#3099] address 3rd PR review - getSyntax clarity, primitive-array RRF, no boxing

- vectorDequantizeInt8.getSyntax(): repeat the function name on both alternatives so neither reads as a
  bare tuple.
- vectorRRFScore: iterate primitive rank arrays (int[]/long[]/float[]/double[]) directly instead of
  boxing them into an Object[], per the engine's GC-awareness policy. Object[]/List still skip nulls.
  Validation (positive integer) is shared by both forms via rankTerm().

* fix: [#3099] vectorDequantizeInt8 3-arg form accepts the result object too

The single-arg form already accepted a QuantizationResult, but the issue's literal example uses the
(result, min, max) form: vectorDequantizeInt8(vectorQuantizeInt8([...]), 1.0, 3.0). The 3-arg path now
extracts the bytes from a QuantizationResult as well, so that exact query works instead of throwing
"Quantized vector must be an array or list, found: QuantizationResult".

* fix: [#3099] address 4th PR review - dequantizeInt8 min/max correctness, RRF NaN guard, edge cases

- dequantizeInt8 3-arg form with a QuantizationResult now uses the result's own
  authoritative min/max instead of the explicit scalars, so passing a wrong min/max
  alongside the result object no longer silently dequantizes with the wrong scale.
  Removed the now-dead QuantizationResult branch in toByteArray.
- RRFScore rankTerm now guards NaN/Infinity up front with a dedicated 'must be finite'
  message instead of letting them fall through to the misleading 'must be integers' error.
- approxDistance INT8 path gives a helpful error naming the expected INT8 inputs when a
  BinaryQuantizationResult is passed (mixed types in the explicit 3-arg form).
- Clarified inferType comment ('each argument must be a recognized result object').
- Documented the intentional separator leniency in VectorUtils string parsing.
- Documented SQLMethodAsSparse shared-instance thread-safety; asSparse Javadoc arrow nit.
- Tests: result-own-min/max wins, non-finite ranks rejected, explicit-type mixed-type
  message, and the SQL asSparse() path now asserts the returned SparseVector value (45 tests).

* test: fix phase6VectorStatistics type witness (AVG returns Double, not Float)

AVG() returns a Double (issue #4518), so result.<Float>getProperty(...) on the
AVG-wrapped avg_magnitude/sparsity_pct columns threw a ClassCastException. Use the
matching <Double> witness.

* fix: [#3099] address 5th PR review - dequantizeInt8 null-scalar ordering bug

- BUG: dequantizeInt8(result, null, null) returned null instead of using the result
  object's embedded min/max, because the scalar null-guard fired before the
  QuantizationResult check. Moved the QuantizationResult early-exit above the null-guard
  so embedded min/max always win, even with null/wrong explicit scalars.
- getSyntax() compacted to a single form (NAME + '(<result> | <quantized_bytes>, <min>, <max>)'),
  matching the convention used by approxDistance.
- Documented why float[]/double[] rank arrays are safe (rankTerm rejects any non-integer
  regardless of array type, so a precision-lost float cannot slip through).
- Tests: (result, null, null) uses embedded min/max; explicit 'BINARY' with INT8 result
  objects surfaces a CommandSQLParsingException naming BinaryQuantizationResult (not a raw
  ClassCastException). Replaced fully-qualified java.util names with imports (47 tests).

* fix: [#3099] address 6th PR review - rrfFromArray docs/AssertionError, dequantizeInt8 syntax hint, no-space semicolon test

* fix: [#3099] address 7th PR review - dequantizeInt8 syntax/Javadoc, RRF rejects float[]/double[] rank arrays, inferType readability

* test: [#4643] update SEARCH_FIELDS_MORE nonExistentRID expectation to function's own "Record not found" message (missing-bucket lookup no longer throws after #4643)

* fix: [#3099] address 8th PR review - document Object[] inclusion in RRF isArrayLike, skip unused separator computation for PRETTY format

* fix: [#3099] address 9th PR review - dequantizeInt8 getSyntax shows both forms + clarified ignored-scalar contract, RRF short[] note, tighter binary error assertion

* fix: [#3099] address 10th PR review - dequantizeInt8 rejects conflicting (non-matching) explicit min/max with a result, 2-arg comment, stateless contract on denseToSparse

* docs: [#3099] address 11th PR review - explain why rankTerm uses Math.rint over a (long) cast for the integer check

* fix: [#3099] address 12th PR review - tighten+document dequantize tolerance (1e-5), clarify isArrayLike/RRF syntax/denseToSparse contract comments, test annotations
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant