Difference between revisions of "Containers"
Line 31: | Line 31: | ||
New types are registered via netsnmp_container_register() and netsnmp_container_register_with_compare(). | New types are registered via netsnmp_container_register() and netsnmp_container_register_with_compare(). | ||
− | ==MIB indexes vs | + | ==Getting a Container== |
+ | To get a container of a particular type, | ||
+ | netsnmp_container_find("type1:type2"); | ||
+ | |||
+ | This will search for a container of "type1", and if not found, of "type2". It is a good idea to specify a custom name each time that you use a container. In the future, it will be possible to specify that certain tokens should map to certain container types. For example, say you are using a container while implementing the XyzWidgetMib, and you wanted to use a linked list, you could create your container like so: | ||
+ | container = netsnmp_container_find("XyzWidgetMib:linked_list"); | ||
+ | |||
+ | This would use a linked list container, and (once implemented), allow runtime-configuration to change the container type to a binary array, should the linked list perform poorly with a large data set. | ||
+ | |||
+ | |||
+ | ==MIB indexes vs Container indexes== | ||
SNMP tables have indexes. A table index may have multiple components which, | SNMP tables have indexes. A table index may have multiple components which, | ||
taken together, uniquely identify a row. | taken together, uniquely identify a row. |
Revision as of 23:11, 20 December 2006
Some (incomplete) ramblings about netsnmp_containers...
Contents
Introduction
Containers are a generic data interface, similar to a database. Like a database, you use an index (aka key) to access and sort the data. Containers use a compare function provided by the user to determine the sort order. The function is called with a pointer to two data itmes, and must return a value indicating which of the two has the lesser index value.
Types of Containers
There are several base types of containers:
- sorted_singly_linked_list
- unsorted_singly_linked_list
- lifo (a last in, first out stack)
- fifo (a first in, first out stack)
- binary_array
- null (for testing)
Some of these have aliases:
- table_container (binary_array)
- linked_list (sorted_singly_linked_list)
- ssll_container (sorted_singly_linked_list)
Some types also come with a comparison routine other than the usual OID index:
- string or string:binary_array (binary_array with a string comparison function)
Developer Tip: New types are registered via netsnmp_container_register() and netsnmp_container_register_with_compare().
Getting a Container
To get a container of a particular type,
netsnmp_container_find("type1:type2");
This will search for a container of "type1", and if not found, of "type2". It is a good idea to specify a custom name each time that you use a container. In the future, it will be possible to specify that certain tokens should map to certain container types. For example, say you are using a container while implementing the XyzWidgetMib, and you wanted to use a linked list, you could create your container like so:
container = netsnmp_container_find("XyzWidgetMib:linked_list");
This would use a linked list container, and (once implemented), allow runtime-configuration to change the container type to a binary array, should the linked list perform poorly with a large data set.
MIB indexes vs Container indexes
SNMP tables have indexes. A table index may have multiple components which, taken together, uniquely identify a row.
Now, when the two are used together, it easy to get confused. All of the MIB indexes, taken together, are the primary container index. Even if a MIB table has a dozen indexes, the container only has one.
To clarify futher, here's an example. Let's say we are creating a SNMP interface to a hotel reservation system. The (simplified) table looks like this:
guestTable
guestEntry INDEX { building, room } building INTEGER room INTEGER name STRING
So, the MIB has two indexes, the building and room numbers. The primary MIB index is the building, and the secondary MIB index is the room. However, the primary index of the container will be the combined index OIDs (building.room).
Comparison routines
The default compare routine for containers assumes that the data record's first component is a netsnmp_index, so when using an OID as a key, you don't need to provide a comparison routine. By providing a second compare function, you can to access the data in a different order. If you wanted to provide your own compare routine, the primary container index compare function might look something like this:
int netsnmp_compare_netsnmp_index(guestTable *lh_guest, guestTable *rh_guests) { /* compare building, then room */ if(lh_guest->building == rh_guest->building) { if(lh_guest->room == rh_guest->room) return 0; else { if(lh_guest->room < rh_guest->room) return -1; else return 1; } } else { if(lh_guest->building < rh_guest->building) return -1; else return 1; } }
So we now have a container with the guest data, and we can look up data by building and room number. What if our application now needs to generate a guest report, but sorted by name? We have the data, but in the wrong sort order. This is where you would use a secondary index to the container. The new compare might look like this:
int netsnmp_compare_netsnmp_index(guestTable *lh_guest, guestTable *rh_guests) { /* compare name, then building and room */ int rc = strcmp(lh_guest->name,rh_guest->name); if(rc != 0) return rc; if(lh_guest->building == rh_guest->building) { if(lh_guest->room == rh_guest->room) return 0; else { if(lh_guest->room < rh_guest->room) return -1; else return 1; } } else { if(lh_guest->building < rh_guest->building) return -1; else return 1; } }