Skip to content

Commit

Permalink
Fix and improve rearrange (#44)
Browse files Browse the repository at this point in the history
  • Loading branch information
vearutop authored Sep 25, 2021
1 parent d223be0 commit bb3e3b4
Show file tree
Hide file tree
Showing 7 changed files with 1,376 additions and 18 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [3.8.3] - 2021-09-25

### Fixed
- Redundant operations in array patches that strip first element.
- XOR hash collision for properties having equal parts.

### Added
- Rearrange indexing by non-scalar properties that contain object, using XOR hash.

## [3.8.2] - 2021-09-17

### Fixed
Expand Down Expand Up @@ -60,6 +69,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Compatibility option to `TOLERATE_ASSOCIATIVE_ARRAYS` that mimic JSON objects.

[3.8.3]: https://github.com/swaggest/json-diff/compare/v3.8.2...v3.8.3
[3.8.2]: https://github.com/swaggest/json-diff/compare/v3.8.1...v3.8.2
[3.8.1]: https://github.com/swaggest/json-diff/compare/v3.8.0...v3.8.1
[3.8.0]: https://github.com/swaggest/json-diff/compare/v3.7.5...v3.8.0
Expand Down
38 changes: 24 additions & 14 deletions src/JsonDiff.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,7 @@ class JsonDiff
private $jsonPatch;

/** @var JsonHash */
private $jsonHashOriginal;

/** @var JsonHash */
private $jsonHashNew;
private $jsonHash;

/**
* @param mixed $original
Expand Down Expand Up @@ -410,7 +407,7 @@ private function rearrangeArray(array $original, array $new)
/** @var mixed[string] $f */
$f = get_object_vars($first);
foreach ($f as $key => $value) {
if (is_array($value) || $value instanceof \stdClass) {
if (is_array($value)) {
continue;
}

Expand All @@ -425,11 +422,19 @@ private function rearrangeArray(array $original, array $new)
break;
}
$value = $item->$key;
if ($value instanceof \stdClass || is_array($value)) {
if (is_array($value)) {
$keyIsUnique = false;
break;
}

if ($value instanceof \stdClass) {
if ($this->jsonHash === null) {
$this->jsonHash = new JsonHash($this->options);
}

$value = $this->jsonHash->xorHash($value);
}

if (isset($uniqueIdx[$value])) {
$keyIsUnique = false;
break;
Expand Down Expand Up @@ -461,10 +466,18 @@ private function rearrangeArray(array $original, array $new)

$value = $item->$uniqueKey;

if ($value instanceof \stdClass || is_array($value)) {
if (is_array($value)) {
return $new;
}

if ($value instanceof \stdClass) {
if ($this->jsonHash === null) {
$this->jsonHash = new JsonHash($this->options);
}

$value = $this->jsonHash->xorHash($value);
}


if (isset($uniqueIdx[$value])) {
$idx = $uniqueIdx[$value];
Expand All @@ -490,26 +503,24 @@ private function rearrangeArray(array $original, array $new)
}

ksort($newRearranged);
$newRearranged = array_values($newRearranged);
return $newRearranged;
}

private function rearrangeEqualItems(array $original, array $new)
{
if ($this->jsonHashOriginal === null) {
$this->jsonHashOriginal = new JsonHash($this->options);
$this->jsonHashNew = new JsonHash($this->options);
if ($this->jsonHash === null) {
$this->jsonHash = new JsonHash($this->options);
}

$origIdx = [];
foreach ($original as $i => $item) {
$hash = $this->jsonHashOriginal->xorHash($item);
$hash = $this->jsonHash->xorHash($item);
$origIdx[$hash][] = $i;
}

$newIdx = [];
foreach ($new as $i => $item) {
$hash = $this->jsonHashNew->xorHash($item);
$hash = $this->jsonHash->xorHash($item);
$newIdx[$i] = $hash;
}

Expand All @@ -535,7 +546,6 @@ private function rearrangeEqualItems(array $original, array $new)
}

ksort($newRearranged);
$newRearranged = array_values($newRearranged);

return $newRearranged;
}
Expand Down
2 changes: 1 addition & 1 deletion src/JsonHash.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public function xorHash($data, $path = '')
foreach ($dataKeys as $key => $value) {
$propertyPath = $path . '/' .
JsonPointer::escapeSegment($key, (bool)($this->options & JsonDiff::JSON_URI_FRAGMENT_ID));
$propertyHash = $propertyPath . $this->xorHash($value, $propertyPath);
$propertyHash = $propertyPath . md5($key, true) . $this->xorHash($value, $propertyPath);
if (strlen($xorHash) < strlen($propertyHash)) {
$xorHash = str_pad($xorHash, strlen($propertyHash));
}
Expand Down
Loading

0 comments on commit bb3e3b4

Please sign in to comment.