DEV Community

Peter + AI
Peter + AI

Posted on

🎯 Mastering Uniface's `discard` Statement: Memory Management in Batch Operations

πŸ” What is the discard Statement?

The discard statement in Uniface is a powerful tool for memory management that removes one or more occurrences from components and hitlists. It's particularly valuable for optimizing performance in large batch operations. πŸƒβ€β™‚οΈ

πŸ“ Basic Syntax

discard {Entity} {, FromOccurrence {, ToOccurrence}}
Enter fullscreen mode Exit fullscreen mode

Example:

discard "CUSTOMER", 1000
Enter fullscreen mode Exit fullscreen mode

πŸ› οΈ Parameters

Parameter Data Type Description
Entity String Entity to be discarded. If omitted, occurrences are removed from the current entity
FromOccurrence Number Position of the occurrence in the hitlist (integer)
ToOccurrence Number End position for range operations (integer)

πŸ“Š Return Values ($status)

  • >0: πŸŽ‰ Sequence number of the current occurrence after discarding
  • 0: βœ… Successfully discarded, no next occurrence available
  • -1: ❌ FromOccurrence exceeds available occurrences
  • -2: ❌ Entity doesn't exist or isn't painted in component
  • -3: πŸ”’ Component is locked for updates

🎯 Key Use Cases

1. πŸš€ Memory Optimization in Batch Jobs

The primary purpose of discard is to release memory during large batch operations, significantly improving performance:

operation exec
    retrieve
    if ($status < 0)
        return ($status)
    endif
    repeat
        ; Process current occurrence here
        discard "ENTITY"
        if ($status = 0)
            setocc "ENTITY", $curocc("ENTITY") + 1
        endif
    until ($status < 0)
end
Enter fullscreen mode Exit fullscreen mode

2. πŸ“‹ Range Operations

You can discard multiple occurrences at once:

  • discard "ENTITY", 5, 10 - Discards occurrences 5-10
  • discard "ENTITY", 5 - Discards occurrence 5
  • discard "ENTITY", -1 - Discards the last occurrence

⚠️ Important Considerations

πŸ”„ Using discard in Read Triggers

Critical: When using discard in a read trigger of the same entity, the trigger terminates immediately after the discard to prevent stack overflow errors:

; ❌ Problematic approach
trigger: Read
read
$1 = PKEY
if (INVDATE < $date("1-jan-96"))
    discard
    putmess "Discarded: %%$1"  ; This will NOT execute!
endif
putmess "Kept: %%$1"
Enter fullscreen mode Exit fullscreen mode

πŸ—οΈ Best Practice for Inner/Outer Entities

Instead of discarding from inner entity read triggers, use a flag-based approach:

; βœ… Recommended approach
; outer entity CUSTOMER
trigger read
    $RECENT_ORDER$ = FALSE
    read
    setocc "ORDER", -1
    if ($RECENT_ORDER$ = TRUE)
        discard "CUSTOMER"
    endif

; inner entity ORDER  
trigger read
    if (DATE_OF_ORDER > $CUTOFF_DATE$)
        $RECENT_ORDER$ = TRUE
    endif
end
Enter fullscreen mode Exit fullscreen mode

🧠 Memory Management Impact

The discard statement affects several system variables:

  • $curocc - Current occurrence number
  • $curhits - Current hitlist size
  • $dbocc - Database occurrence count
  • $hits - Total hits
  • $totdbocc and $totocc - Total occurrence counts

πŸŽ–οΈ Pro Tips

  1. πŸ• Timing Matters: Keep the time between processing and discarding occurrences as short as possible for optimal performance
  2. πŸ” Outside Read Triggers: When using discard outside read triggers, be aware that $status = 0 doesn't necessarily mean no more data exists
  3. ⚑ Performance: Use discard strategically in batch processes to prevent memory bloat
  4. πŸ›‘οΈ Error Handling: Always check $status and $procerror values for robust error handling

πŸŽ‰ Conclusion

The discard statement is an essential tool for Uniface developers working with large datasets. When used correctly, it can dramatically improve application performance by managing memory efficiently. Remember to follow best practices, especially when dealing with read triggers and nested entities! πŸ’ͺ


πŸ“š Based on Uniface 10.4 documentation | πŸ€– Article created with AI assistance

Top comments (0)