+ if ( overlay.source.dirty++ > 1000 ) {
+ fsync( overlay.source.fd );
+ overlay.source.dirty = 0;
+ }
+}
+
+/**
+ * Insert a new region at index p, with previous portion [p,count]
+ * moved up to make space.
+ */
+static void overlay_insert(size_t p,off_t beg,off_t end) {
+ size_t bytes;
+ // Grow the table if needed
+ if ( overlay.count >= overlay.limit ) {
+ overlay.limit = overlay.count + 10;
+ bytes = overlay.limit * sizeof( struct Region );
+ overlay.table = overlay.table?
+ realloc( overlay.table, bytes ) : malloc( bytes );
+ }
+ bytes = ( overlay.count++ - p ) * sizeof( struct Region );
+ if ( bytes ) {
+ memmove( (char*) &overlay.table[ p+1 ],
+ (char*) &overlay.table[ p ],
+ bytes );
+ }
+ overlay.table[ p ].beg = beg;
+ overlay.table[ p ].end = end;
+ overlay_save_count();
+}
+
+/**
+ * Delete the region entry at p by moving the portion [p+1,count]
+ * down.
+ */
+static void overlay_delete(size_t p) {
+ size_t bytes = ( --overlay.count - p ) * sizeof( struct Region );
+ if ( bytes ) {
+ memmove( (char*) &overlay.table[ p ],
+ (char*) &overlay.table[ p+1 ],
+ bytes );
+ }
+}
+
+/**
+ * Mark the given region as updated, i.e. written to the overlay. The
+ * mark region may attach to prior marked regions or be a new,
+ * separate region. If attaching, it causes the prior regions to
+ * expand and the table adjusted by deleting any regions that become
+ * fully contained in other regions.
+ */
+static void overlay_mark(off_t beg,off_t end) {
+#if DEBUG
+ fprintf( stderr, "overlay_mark( %ld, %ld )\n", beg, end );
+#endif
+ int deleted = 0;
+ ssize_t q;
+ ssize_t p = overlay_prior_fragment( beg );
+ // p is the nearest region below or at beg (or -1)
+ if ( p >= 0 && beg <= overlay.table[p].end ) {
+ // p overlaps mark region
+ if ( end <= overlay.table[p].end ) {
+ // region p covers mark region already
+#if DEBUG
+ fprintf( stderr, "overlay covering ( %ld %ld )\n",
+ overlay.table[p].beg, overlay.table[p].end );
+#endif
+ return;
+ }
+ // the new mark region extends region p
+ overlay.table[p].end = end;
+ q = p+1;
+ while ( q < overlay.count &&
+ overlay.table[q].beg <= overlay.table[p].end ) {
+ // Extended region merges with subsequent region
+ if ( overlay.table[p].end < overlay.table[q].end ) {
+ overlay.table[p].end = overlay.table[q].end;
+ }
+ overlay_delete( q );
+ deleted++;
+ }
+ if ( deleted ) {
+ overlay_save_count();
+ q = overlay.count;
+ }
+ overlay_save_table( p, q );