#lang scribble/manual @(require scribble/eval "utils.rkt" (for-label unstable/interval-map racket/contract racket/dict racket/base)) @title[#:tag "interval-map"]{Interval Maps} @(define the-eval (make-base-eval)) @(the-eval '(require unstable/interval-map)) @(the-eval '(require racket/dict)) @defmodule[unstable/interval-map] @unstable[@author+email["Ryan Culpepper" "ryanc@racket-lang.org"]] An interval-map is a mutable dictionary-like data structure where mappings are added by @emph{half-open} intervals and queried by discrete points. Interval-maps can be used with any total order. Internally, an interval-map uses a skip-list (@racketmodname[unstable/skip-list]) of intervals for efficient query and update. Interval-maps implement the dictionary (@racketmodname[racket/dict]) interface to a limited extent. Only @racket[dict-ref] and the iteraction-based methods (@racket[dict-iterate-first], @racket[dict-map], etc) are supported. For the iteration-based methods, the mapping's keys are considered the pairs of the start and end positions of the mapping's intervals. @examples[#:eval the-eval (define r (make-numeric-interval-map)) (interval-map-set! r 1 5 'apple) (interval-map-set! r 6 10 'pear) (interval-map-set! r 3 6 'banana) (dict-map r list) ] @defproc[(make-interval-map [=? (any/c any/c . -> . any/c)] [ . any/c)] [translate (or/c (any/c any/c . -> . (any/c . -> . any/c)) #f) #f]) interval-map?]{ Makes a new empty interval-map. The interval-map uses @racket[=?] and @racket[ . any/c)] [default any/c (lambda () (error ....))]) void?]{ Updates @racket[interval-map], associating every position in [@racket[start], @racket[end]) with the result of applying @racket[updater] to the position's previously associated value, or to the default value produced by @racket[default] if no mapping exists. Unlike @racket[interval-map-set!], @racket[interval-map-update*!] preserves existing distinctions within [@racket[start], @racket[end]). } @defproc[(interval-map-remove! [interval-map interval-map?] [start any/c] [end any/c]) void?]{ Removes the value associated with every position in [@racket[start], @racket[end]). } @defproc[(interval-map-expand! [interval-map interval-map-with-translate?] [start any/c] [end any/c]) void?]{ Expands @racket[interval-map]'s domain by introducing a gap [@racket[start], @racket[end]) and adjusting intervals after @racket[start] using @racket[(_translate start end)]. If @racket[interval-map] was not constructed with a @racket[_translate] argument, an exception is raised. If @racket[start] is not less than @racket[end], an exception is raised. } @defproc[(interval-map-contract! [interval-map interval-map-with-translate?] [start any/c] [end any/c]) void?]{ Contracts @racket[interval-map]'s domain by removing all mappings on the interval [@racket[start], @racket[end]) and adjusting intervals after @racket[end] using @racket[(_translate end start)]. If @racket[interval-map] was not constructed with a @racket[_translate] argument, an exception is raised. If @racket[start] is not less than @racket[end], an exception is raised. } @defproc[(interval-map-cons*! [interval-map interval-map?] [start any/c] [end any/c] [v any/c] [default any/c null]) void?]{ Same as the following: @racketblock[ (interval-map-update*! interval-map start end (lambda (old) (cons v old)) default) ] } @defproc[(interval-map-iter? [v any/c]) boolean?]{ Returns @racket[#t] if @racket[v] represents a position in an interval-map, @racket[#f] otherwise. }