title: Algorithm to convert offset pagination to page number pagination
body: <p>I have a service that must receive pagnation queries in offset format, receiving <code>offset</code> and <code>limit</code> parameters. For example, if I receive <code>offset=5&amp;limit=10</code>, I would expect to receive items 5-14 back. I am able to enforce some validation against these parameters, for example to set a maximum value for limit.</p>
  <p>My data source must receive pagination requests in page number format, receiving <code>page_number</code> and <code>page_size</code> parameters. For example, if I send <code>page_number=0&amp;page_size=20</code>, I would receive items 0-19. The data source has a maximum <code>page_size</code> of 100.</p>
  <p>I need to be able to take the offset pagination parameters I receive and use them to determine appropriate values for the <code>page_number</code> and <code>page_size</code> parameters, in order to return a range from the data source that includes all of the items I need. Additional items may be returned padding out the start and/or end of the range, which can then be filtered out to produce the requested range.</p>
  <p>If possible, I should only make a single request to the data source. Optionally, performance can be improved by minimising the size of the range to be requested from the datasource (i.e. fetching 10 items to satisfy a request for 8 items is more efficient than requesting 100 items for the same).</p>
  <p>This feels like it should be relatively simple to achieve, but my attempts at simple mathematical solutions don't address all of the edge cases, and my attempts at more robust solutions have started to head into the more complex space of calculating and iterating over factors etc.</p>
  <p>Is there a simple way to calculate the appropriate values?</p>
  <p><a href="https://replit.com/@JimAllanson/pagination-translation-tests" rel="nofollow noreferrer">I've put together a test harness REPL with a set of example test cases that makes it easy to trial different implementations here.</a></p>