Skip to content

Commit

Permalink
Address O(N^2) and malloc fail problems from https://codereview.stack…
Browse files Browse the repository at this point in the history
  • Loading branch information
LivInTheLookingGlass committed Oct 1, 2024
1 parent b29a707 commit bf9f0de
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 22 deletions.
60 changes: 38 additions & 22 deletions fortran/src/include/utils.f90
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ module utils
integer(kind=1) :: type
end type AnswerT

logical(kind=1) :: cache_inited = .false.
type(AnswerT), dimension(1024) :: cached_answers

contains
function get_data_file(filename) result(contents)
character(len=*), intent(in) :: filename
Expand All @@ -27,6 +30,10 @@ function get_data_file(filename) result(contents)
inquire(unit=unit_number, size=file_size)
if (file_size > 0) then
allocate(character(len=file_size) :: contents)
if (.not. allocated(contents)) then
print *, "Failed to allocate memory for read. Exiting."
stop -3
end if
contents = ''
do
read(unit_number, '(A)', iostat=iostat) line
Expand All @@ -52,6 +59,15 @@ function get_answer(id) result(answer)
character(len=32) :: val
character(len=4) :: id_, type_, length

if (cache_inited) then
answer = cached_answers(id)
return
end if

do i=1, size(cached_answers)
cached_answers(i)%type = errort
end do

text = get_data_file("answers.tsv")
if (.not. allocated(text)) then
text = '' ! Ensure text is defined if allocation failed
Expand All @@ -75,34 +91,34 @@ function get_answer(id) result(answer)
read(id_, *, iostat=ios) i
if (ios /= 0) then
print *, "Invalid integer literal for id. Moving on without explicit error, but please debug this"
elseif (i == id) then
select case (type_)
case ("int", "uint")
read(val, *, iostat=ios) i
if (ios /= 0) then
print *, "Invalid integer literal for value. Returning error type"
else
answer%type = int64t
answer%int_value = i
end if
case ("str")
allocate(character(len=len(trim(val))) :: answer%string_value)
if (.not. allocated(answer%string_value)) then
print *, "Memory allocation failed for string_value. Returning error type"
else
answer%type = stringt
answer%string_value = trim(val)
end if
case default
print *, "Invalid value type. Returning error type"
end select
return
end if
select case (type_)
case ("int", "uint")
read(val, *, iostat=ios) i
if (ios /= 0) then
print *, "Invalid integer literal for value. Returning error type"
else
cached_answers(i)%type = int64t
cached_answers(i)%int_value = i
end if
case ("str")
allocate(character(len=len(trim(val))) :: cached_answers(i)%string_value)
if (.not. allocated(cached_answers(i)%string_value)) then
print *, "Memory allocation failed for string_value. Returning error type"
else
cached_answers(i)%type = stringt
cached_answers(i)%string_value = trim(val)
end if
case default
print *, "Invalid value type. Returning error type"
end select
row_start = row_start + line_length ! Move to the next line
end if
end do

deallocate(text)
cache_inited = .true.
answer = get_answer(id)
end function

subroutine parse_line(line, id_out, type_out, length_out, value_out)
Expand Down
4 changes: 4 additions & 0 deletions fortran/test.f90
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ program test
num_problems = 7
allocate(problem_ids(num_problems))
allocate(long_runtime(num_problems))
if (.not. (allocated(problem_ids) .and. allocated(long_runtime))) then
print *, "Could not allocate problem list. Exiting."
stop -2
end if
problem_ids = (/ &
001, &
002, &
Expand Down

0 comments on commit bf9f0de

Please sign in to comment.