{'fraction_non_alphanumeric': 0.03235679930039353, 'fraction_numerical': 0.0017490161783996502, 'mean_word_length': 4.5, 'pattern_counts': {'":': 0, '<': 0, '<?xml version=': 0, '>': 0, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
Extending Java with Checkpointing

In this project, an incremental checkpointing mechanism is developed for Java. By making the abstraction that program state is the state of variables, this checkpointing mechanism gives the assurance that the program can be rolled back to its previous state when error occurs. A language construct that ensures this data integrity is invented with a syntax similar to Java’s try-catchfinally construct. Transformation from a program written with this new construct to a native Java program is studied. An tool is implemented to automate this transformation. 1 The Problem of Maintaining Program State Exceptions as a language feature are supported by a number of contemporary programming languages. The use of exceptions and the corresponding try-catch-finally construct simplifies error handling in programs. However, correct use of the try-catch-finally construct does not guarantee correct handling of exceptions. Although the program execution recovers from the exception, the program state may be inconsistent from that point. Figure 1 shows a program fragment in Java. It may invalidate its execution state after the occurrence of an IO exception. This code tries to read from an input stream, and then append the received data to the non-empty buffer. However, if an IOException happens in the loop, the execution of the loop will not be complete. Though the exception is caught and handled, the state of the program, which includes buffer and bufIndex in this case, is no longer consistent. What the programmer really wants is to read the data into the buffer, but if the read is not complete, neither the buffer nor its index should be changed, as if no read operation were issued. A simple-minded attempt to correct the problem results in another program in Figure 2. This time, a full backup of the program state is created before the try block is entered. If an IOException occurs, the program state is restored with the backup. However, this modification only partly solves the problem. The (*) statement is problematic. If the reference of buffer was copied to another variable before, int[] buffer = ... // A buffer int bufIndex = 0; // The current index of the buffer ... bufIndex = ... // Current location of the buffer (not empty) ...