@@ -104,19 +104,7 @@ func (r *Reader) startNode() (uint, error) {
104104}
105105
106106// Lookup takes an IP address as a net.IP structure and a pointer to the
107- // result value to decode into. The result value pointed to must be a data
108- // value that corresponds to a record in the database. This may include a
109- // struct representation of the data, a map capable of holding the data or an
110- // empty interface{} value.
111- //
112- // If result is a pointer to a struct, the struct need not include a field
113- // for every value that may be in the database. If a field is not present in
114- // the structure, the decoder will not decode that field, reducing the time
115- // required to decode the record.
116- //
117- // Currently the decoder expect most data types to correspond exactly (e.g.,
118- // a uint64 database type must be decoded into a uint64 Go type). In the
119- // future, this may be made more flexible.
107+ // result value to Decode into.
120108func (r * Reader ) Lookup (ipAddress net.IP , result interface {}) error {
121109 if pointer , err := r .lookupPointer (ipAddress ); pointer == 0 {
122110 return err
@@ -125,8 +113,11 @@ func (r *Reader) Lookup(ipAddress net.IP, result interface{}) error {
125113 }
126114}
127115
128- // LookupOffset maps an argument net.IP to corresponding root record offset
129- // in the database. NotFound is returned if no such record is found.
116+ // LookupOffset maps an argument net.IP to a corresponding record offset in the
117+ // database. NotFound is returned if no such record is found, and a record may
118+ // otherwise be extracted by passing the returned offset to Decode. LookupOffset
119+ // is an advanced API, which exists to provide clients with a means to cache
120+ // previously-decoded records.
130121func (r * Reader ) LookupOffset (ipAddress net.IP ) (uintptr , error ) {
131122 if pointer , err := r .lookupPointer (ipAddress ); pointer == 0 {
132123 return NotFound , err
@@ -135,7 +126,26 @@ func (r *Reader) LookupOffset(ipAddress net.IP) (uintptr, error) {
135126 }
136127}
137128
138- // Decodes the record at |offset| into |result|.
129+ // Decodes the record at |offset| into |result|. The result value pointed to
130+ // must be a data value that corresponds to a record in the database. This may
131+ // include a struct representation of the data, a map capable of holding the
132+ // data or an empty interface{} value.
133+ //
134+ // If result is a pointer to a struct, the struct need not include a field
135+ // for every value that may be in the database. If a field is not present in
136+ // the structure, the decoder will not decode that field, reducing the time
137+ // required to decode the record.
138+ //
139+ // As a special case, a struct field of type uintptr will be used to capture
140+ // the offset of the value. Decode may later be used to extract the stored
141+ // value from the offset. MaxmindDBs are highly normalized: for example in the
142+ // Cities database, all records of the same country will reference a single
143+ // representative record for that country. This uintptr behavior allows clients
144+ // to leverage this normalization in their own sub-record caching.
145+ //
146+ // Currently the decoder expect most data types to correspond exactly (e.g.,
147+ // a uint64 database type must be decoded into a uint64 Go type), with the
148+ // exception of uintptr. In the future, this may be made more flexible.
139149func (r * Reader ) Decode (offset uintptr , result interface {}) error {
140150 rv := reflect .ValueOf (result )
141151 if rv .Kind () != reflect .Ptr || rv .IsNil () {
0 commit comments