file_fingerprint Function

public function file_fingerprint(path) result(fp)

Compute a fingerprint for a file path.

Strategy: - Read the file size (inquire(size=...)). - Hash up to three blocks (head/mid/tail) using FNV-1a mixing. - Combine with file size to reduce collision risk.

Missing/unreadable files return 0.

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: path

Return Value integer(kind=int64)


Calls

proc~~file_fingerprint~~CallsGraph proc~file_fingerprint file_fingerprint proc~hash_block hash_block proc~file_fingerprint->proc~hash_block proc~fnv1a_mix_i64 fnv1a_mix_i64 proc~hash_block->proc~fnv1a_mix_i64

Called by

proc~~file_fingerprint~~CalledByGraph proc~file_fingerprint file_fingerprint proc~init_fingerprints init_fingerprints proc~init_fingerprints->proc~file_fingerprint proc~manifest_key_from_files manifest_key_from_files proc~manifest_key_from_files->proc~file_fingerprint proc~scan_changes scan_changes proc~scan_changes->proc~file_fingerprint proc~handle_manifest_change handle_manifest_change proc~handle_manifest_change->proc~manifest_key_from_files proc~rebuild_watch_list rebuild_watch_list proc~handle_manifest_change->proc~rebuild_watch_list proc~rebuild_watch_list->proc~init_fingerprints proc~rebuild_watch_list->proc~manifest_key_from_files proc~watcher_run watcher_t%watcher_run proc~watcher_run->proc~scan_changes proc~watcher_run->proc~handle_manifest_change proc~watcher_run->proc~rebuild_watch_list proc~watcher_init watcher_t%watcher_init proc~watcher_init->proc~rebuild_watch_list

Source Code

   integer(int64) function file_fingerprint(path) result(fp)
      character(len=*), intent(in) :: path
      logical :: ex
      integer(int64) :: sz, h, n64, pos_mid, pos_end, pos_max
      integer :: u, ios, n

      inquire(file=trim(path), exist=ex, size=sz, iostat=ios)
      if (ios /= 0 .or. .not. ex) then
         fp = 0_int64
         return
      end if
      if (sz <= 0_int64) then
         fp = 0_int64
         return
      end if

      n64 = min(sz, int(BLOCK_SIZE, int64))
      n = int(n64)

      open(newunit=u, file=trim(path), access="stream", form="unformatted", action="read", status="old", iostat=ios)
      if (ios /= 0) then
         fp = ieor(ishft(sz, 1), FNV_OFFSET)
         return
      end if

      if (.not. allocated(io_buf)) allocate(io_buf(BLOCK_SIZE))

      h = FNV_OFFSET
      call hash_block(u, 1_int64, n, h)

      if (sz > n64) then
         pos_max = max(1_int64, sz - n64 + 1_int64)

         pos_mid = sz / 2_int64 - n64 / 2_int64
         if (pos_mid < 1_int64) pos_mid = 1_int64
         if (pos_mid > pos_max) pos_mid = pos_max

         pos_end = pos_max

         call hash_block(u, pos_mid, n, h)
         call hash_block(u, pos_end, n, h)
      end if

      close(u)

      fp = ieor(ishft(sz, 1), h)
   end function file_fingerprint