2 min read

How to Implement a Simple Paging Model

Paging complexity centers around the first index to load.
How to Implement a Simple Paging Model

What is Paging?

Paging is where you only load a portion or a "page" of a full dataset at a time. Paging doesn't need to be difficult. Paging involves four different variables.

First Index

The index of the first record to start at in the dataset for a page of results. To load the next page of results, you simply increment this variable.

Max Page Size

The maximum amount of records a page of results can have. This will be the size of each page until the last page. The last page will be equal to or less than the maximum page size.

Total Records

The total number of records in the full dataset. You need to know how big the dataset is to know how many pages a dataset will have. This should be calculated each time a page is loaded if your dataset size can change between loads. This number is also probably displayed to the user.

Records

A sorted list of records for a page of results. The number of records will be equal to or less than the max page size.

In Java code, a class with these variables would look something like the following:

// Java code
public final class Page<T> {

    private final List<T> records;
    private final int totalRecords;
    private final int firstResult;
    private final int maxSize;
    
    // Constructor and getters
}

This class holds all of the paging variables listed above.

Simple Paging

Although paging requires each of the variables above, you can simplify paging even further. Depending on your application, the max page size might be a constant value and not be a variable that is required in your paging class.

As you change what page you are on, your paging class will need to be able to update the state of its variables. If your paging object is mutable and allows these values to change, it can cause confusion as to what page you are at in the dataset. To further simplify paging, use an immutable paging object.

A Page class makes more sense calculating the next first result instead of storing the current first result. If the max page size is not a variable you need, you can still calculate if there are additional results using the totalRecords and nextFirstResult variables. An implementation of this would look like the following:

// Java code
public final class Page<T> {

    private final List<T> records;
    private final int totalRecords;
    private final int nextFirstResult;
    private final int maxSize;
    
    public Page(
        final List<T> records,
        final int totalRecords,
        final int firstResult,
        final int maxSize) {
    
        this.records = records;
        this.totalRecords = totalRecords;
        this.nextFirstResult = firstResult + records.size();
        this.maxSize = maxSize;
    }
    
    public List<T> records() {
        return records;
    }
    
    public int totalRecords() {
        return totalRecords;
    }
    
    public int nextFirstResult() {
        return nextFirstResult;
    }
    
    public int maxSize() {
        return maxSize;
    }
}

The nextFirstResult is calculated based off of the number of records in the page, not the max page size. If a record ends up at the end of your dataset that hasn't been loaded, you can load it.

This paging model will handle most use cases. If your paging model is more complex and you are needing to go to different pages, such as the next page, first page, and last page, this can be implemented with simple math using the firstResult and maxSize variables.

Conclusion

Paging is simple. Don't overcomplicate it. By using the current records and the next page index, you can simplify paging in your application.