- if ( is_array( $stat ) ) { // file exists
- // Strongly consistent backends can automatically set "latest"
- $stat['latest'] = $stat['latest'] ?? $latest;
- $this->cheapCache->setField( $path, 'stat', $stat );
- $this->setFileCache( $path, $stat ); // update persistent cache
- if ( isset( $stat['sha1'] ) ) { // some backends store SHA-1 as metadata
- $this->cheapCache->setField( $path, 'sha1',
- [ 'hash' => $stat['sha1'], 'latest' => $latest ] );
- }
- if ( isset( $stat['xattr'] ) ) { // some backends store headers/metadata
- $stat['xattr'] = self::normalizeXAttributes( $stat['xattr'] );
- $this->cheapCache->setField( $path, 'xattr',
- [ 'map' => $stat['xattr'], 'latest' => $latest ] );
+ if ( is_array( $stat ) ) {
+ return $stat;
+ }
+
+ return ( $stat === self::$RES_ERROR ) ? self::STAT_ERROR : self::STAT_ABSENT;
+ }
+
+ /**
+ * Ingest file stat entries that just came from querying the backend (not cache)
+ *
+ * @param array[]|bool[]|null[] $stats Map of (path => doGetFileStat() stype result)
+ * @param bool $latest Whether doGetFileStat()/doGetFileStatMulti() had the 'latest' flag
+ * @return bool Whether all files have non-error stat replies
+ */
+ final protected function ingestFreshFileStats( array $stats, $latest ) {
+ $success = true;
+
+ foreach ( $stats as $path => $stat ) {
+ if ( is_array( $stat ) ) {
+ // Strongly consistent backends might automatically set this flag
+ $stat['latest'] = $stat['latest'] ?? $latest;
+
+ $this->cheapCache->setField( $path, 'stat', $stat );
+ if ( isset( $stat['sha1'] ) ) {
+ // Some backends store the SHA-1 hash as metadata
+ $this->cheapCache->setField(
+ $path,
+ 'sha1',
+ [ 'hash' => $stat['sha1'], 'latest' => $latest ]
+ );
+ }
+ if ( isset( $stat['xattr'] ) ) {
+ // Some backends store custom headers/metadata
+ $stat['xattr'] = self::normalizeXAttributes( $stat['xattr'] );
+ $this->cheapCache->setField(
+ $path,
+ 'xattr',
+ [ 'map' => $stat['xattr'], 'latest' => $latest ]
+ );
+ }
+ // Update persistent cache (@TODO: set all entries in one batch)
+ $this->setFileCache( $path, $stat );
+ } elseif ( $stat === self::$RES_ABSENT ) {
+ $this->cheapCache->setField(
+ $path,
+ 'stat',
+ $latest ? self::$ABSENT_LATEST : self::$ABSENT_NORMAL
+ );
+ $this->cheapCache->setField(
+ $path,
+ 'xattr',
+ [ 'map' => self::XATTRS_FAIL, 'latest' => $latest ]
+ );
+ $this->cheapCache->setField(
+ $path,
+ 'sha1',
+ [ 'hash' => self::SHA1_FAIL, 'latest' => $latest ]
+ );
+ $this->logger->debug(
+ __METHOD__ . ': File {path} does not exist',
+ [ 'path' => $path ]
+ );
+ } else {
+ $success = false;
+ $this->logger->error(
+ __METHOD__ . ': Could not stat file {path}',
+ [ 'path' => $path ]
+ );