Skip to content

Commit

Permalink
batch/savepapers: Actually conserve memory.
Browse files Browse the repository at this point in the history
  • Loading branch information
kohler committed Jan 18, 2024
1 parent ce31469 commit 3f48c15
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 27 deletions.
59 changes: 33 additions & 26 deletions batch/savepapers.php
Original file line number Diff line number Diff line change
Expand Up @@ -307,8 +307,11 @@ function run_one($index, $j) {
return true;
}

/** @param list<object> $jp */
private function _run_main($jp) {
/** @param list<object> &$jl */
private function _run_main(&$jl) {
// prefetch authors together (useful for big updates)
$this->prefetch_authors($jl);

if ($this->add_topics) {
foreach ($this->conf->options()->form_fields() as $opt) {
if ($opt instanceof Topics_PaperOption)
Expand All @@ -322,55 +325,59 @@ private function _run_main($jp) {
}
}

// prefetch authors together (useful for big updates)
$potential_authors = [];
foreach ($jp as $j) {
if (isset($j->authors) && is_array($j->authors)) {
foreach ($j->authors as $au) {
if (is_object($au)
&& isset($au->email)
&& is_string($au->email))
$potential_authors[] = $au->email;
}
}
}
$this->conf->resolve_primary_emails($potential_authors);

$this->conf->delay_logs();
foreach ($jp as $index => &$j) {
for ($index = 0; $index !== count($jl); ++$index) {
$j = $jl[$index];
$jl[$index] = null;
$this->run_one($index, $j);
if ($this->nerrors && !$this->ignore_errors) {
break;
}
$j = null;
gc_collect_cycles();
if ($index % 10 === 9) {
$this->conf->release_logs();
$this->conf->delay_logs();
}
}
$this->conf->release_logs();
unset($j);
}

/** @param list<object> $jl */
private function prefetch_authors($jl) {
$potential_authors = [];
foreach ($jl as $j) {
if (isset($j->authors) && is_array($j->authors)) {
foreach ($j->authors as $au) {
if (is_object($au)
&& isset($au->email)
&& is_string($au->email))
$potential_authors[] = $au->email;
}
}
}
$this->conf->resolve_primary_emails($potential_authors);
}

/** @return 0|1|2 */
function run($content) {
$jp = $jparser = null;
$j = $jparser = null;
if (!$this->json5) {
$jp = json_decode($content);
$j = json_decode($content);
}
if ($jp === null) {
if ($j === null) {
$jparser = (new JsonParser)->flags($this->json5 ? JsonParser::JSON5 : 0);
$jp = $jparser->input($content)->decode();
$j = $jparser->input($content)->decode();
}
if ($jp === null) {
if ($j === null) {
fwrite(STDERR, "{$this->errprefix}invalid JSON: " . $jparser->last_error_msg() . "\n");
++$this->nerrors;
} else if (!is_array($jp) && !is_object($jp)) {
} else if (!is_array($j) && !is_object($j)) {
fwrite(STDERR, "{$this->errprefix}invalid JSON, expected array of objects\n");
++$this->nerrors;
} else {
$this->_run_main(is_object($jp) ? [$jp] : $jp);
$jl = is_object($j) ? [$j] : $j;
$j = $content = null; // release references
$this->_run_main($jl); // consumes `$jl`
}
if ($this->nerrors) {
return $this->ignore_errors && $this->nsuccesses ? 2 : 1;
Expand Down
8 changes: 7 additions & 1 deletion src/paperstatus.php
Original file line number Diff line number Diff line change
Expand Up @@ -1549,12 +1549,18 @@ function execute_save() {
$this->_postexecute_notify();

// The caller should not use `$this->prow` any more, but in case they
// do (e.g. in old tests), invalidate it when convenient.
// do (e.g. in old tests), invalidate it now when it's convenient
// to do so. XXX It would be useful to keep `$this->prow` around...
$this->prow->commit_prop();
$this->prow->invalidate_options();
$this->prow->invalidate_conflicts();
$this->prow->invalidate_documents();

// save new title and clear out memory
$this->title = $this->prow->title();
$this->prow = null;
$this->_field_values = null;
$this->_update_pid_dids = $this->_joindocs = null;
return true;
}

Expand Down

0 comments on commit 3f48c15

Please sign in to comment.