Skip to content

Commit 293bca6

Browse files
committed
Eliminated some unnecessary tree traversals for arrays, which should improve efficiency for large arrays. These updates were inspired by https://github.com/acroucher/fson
1 parent de920fa commit 293bca6

File tree

1 file changed

+52
-63
lines changed

1 file changed

+52
-63
lines changed

src/json_module.f90

Lines changed: 52 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -181,12 +181,16 @@ module json_module
181181

182182
!the data for this variable:
183183
type(json_data_non_polymorphic) :: data
184+
185+
!number of children:
186+
integer,private :: n_children = 0
184187

185188
!for the linked list:
186189
type(json_value), pointer :: previous => null()
187-
type(json_value), pointer :: next => null()
188-
type(json_value), pointer :: parent => null()
190+
type(json_value), pointer :: next => null()
191+
type(json_value), pointer :: parent => null()
189192
type(json_value), pointer :: children => null()
193+
type(json_value), pointer :: tail => null()
190194

191195
end type json_value
192196
!*********************************************************
@@ -1270,9 +1274,14 @@ recursive subroutine json_value_destroy(this)
12701274
call this%data%destroy()
12711275

12721276
if (associated(this%children)) call json_value_destroy(this%children)
1277+
this%n_children = 0
1278+
1279+
if (associated(this%next)) call json_value_destroy(this%next)
12731280

1274-
if (associated(this%next)) call json_value_destroy(this%next)
1275-
1281+
if (associated(this%previous)) nullify(this%previous)
1282+
if (associated(this%parent)) nullify(this%parent)
1283+
if (associated(this%tail)) nullify(this%tail)
1284+
12761285
deallocate(this)
12771286

12781287
nullify(this)
@@ -1329,50 +1338,54 @@ subroutine json_value_remove(me,destroy)
13291338

13301339
type(json_value),pointer :: parent,previous,next
13311340
logical :: destroy_it
1332-
1341+
13331342
if (associated(me)) then
1343+
1344+
!optional input argument:
1345+
if (present(destroy)) then
1346+
destroy_it = destroy
1347+
else
1348+
destroy_it = .true.
1349+
end if
13341350

13351351
if (associated(me%parent)) then
13361352

1337-
!optional input argument:
1338-
if (present(destroy)) then
1339-
destroy_it = destroy
1340-
else
1341-
destroy_it = .true.
1342-
end if
1343-
1353+
parent => me%parent
1354+
13441355
if (associated(me%next)) then
13451356

13461357
!there are later items in the list:
13471358

13481359
next => me%next
13491360
nullify(me%next)
13501361

1351-
if (associated(me%previous)) then
1362+
if (associated(me%previous)) then
13521363
!there are earlier items in the list
13531364
previous => me%previous
13541365
previous%next => next
13551366
next%previous => previous
13561367
else
13571368
!this is the first item in the list
1358-
parent => me%parent
13591369
parent%children => next
1360-
next%previous => null()
1370+
nullify(next%previous)
13611371
end if
13621372

13631373
else
13641374

13651375
if (associated(me%previous)) then
13661376
!there are earlier items in the list:
13671377
previous => me%previous
1368-
previous%next => null()
1378+
nullify(previous%next)
1379+
parent%tail => previous
13691380
else
13701381
!this is the only item in the list:
1371-
parent => me%parent
1372-
parent%children => null()
1382+
nullify(parent%children)
1383+
nullify(parent%tail)
13731384
end if
13741385

1375-
end if
1386+
end if
1387+
1388+
parent%n_children = parent%n_children - 1
13761389

13771390
end if
13781391

@@ -1618,35 +1631,29 @@ subroutine json_value_add_member(this, member)
16181631

16191632
type(json_value), pointer :: this, member
16201633

1621-
type(json_value), pointer :: p
1634+
! type(json_value), pointer :: p
16221635

16231636
if (.not. exception_thrown) then
16241637

1625-
nullify(p)
1626-
16271638
! associate the parent
16281639
member % parent => this
16291640

16301641
! add to linked list
1631-
if (associated(this % children)) then
1632-
1633-
! get to the tail of the linked list
1634-
p => this % children
1635-
do while (associated(p % next))
1636-
p => p % next
1637-
end do
1638-
1639-
p%next => member
1640-
member%previous => p
1642+
if (associated(this%children)) then
16411643

1642-
nullify(p) !cleanup
1644+
this%tail%next => member
1645+
member%previous => this%tail
16431646

16441647
else
16451648

16461649
this%children => member
1647-
member%previous => null()
1650+
member%previous => null() !first in the list
16481651

16491652
end if
1653+
1654+
! new member is now the last one in the list
1655+
this%tail => member
1656+
this%n_children = this%n_children + 1
16501657

16511658
end if
16521659

@@ -2090,39 +2097,20 @@ end subroutine json_value_add_string_vec
20902097
! DESCRIPTION
20912098
! Count the number of children.
20922099
!
2100+
! HISTORY
2101+
! JW : 1/4/2014 : Original routine removed.
2102+
! Now using n_children variable.
2103+
!
20932104
! SOURCE
20942105

2095-
function json_value_count(this) result(count)
2106+
function json_value_count(me) result(count)
20962107

20972108
implicit none
20982109

20992110
integer :: count
2100-
type(json_value),pointer,intent(in) :: this
2101-
2102-
type(json_value), pointer :: p
2103-
2104-
if (.not. exception_thrown) then
2105-
2106-
count = 0
2107-
2108-
if (associated(this)) then
2109-
2110-
if (associated(this%children)) then
2111-
2112-
p => this%children
2113-
2114-
do while (associated(p))
2115-
count = count + 1
2116-
p => p%next
2117-
end do
2118-
2119-
nullify(p)
2120-
2121-
end if
2122-
2123-
end if
2124-
2125-
end if
2111+
type(json_value),pointer,intent(in) :: me
2112+
2113+
count = me%n_children
21262114

21272115
end function json_value_count
21282116
!*****************************************************************************************
@@ -3534,9 +3522,10 @@ subroutine json_get_array(this, path, array_callback, found)
35343522
select case (p%data%var_type)
35353523
case (json_array)
35363524
count = json_value_count(p)
3537-
do i = 1, count
3538-
call json_value_get(p, i, element)
3525+
element => p%children
3526+
do i = 1, count ! callback for each child
35393527
call array_callback(element, i, count)
3528+
element => element%next
35403529
end do
35413530
case default
35423531
call throw_exception('Error in json_get_array:'//&

0 commit comments

Comments
 (0)