diff options
Diffstat (limited to 'doc/developer')
| -rw-r--r-- | doc/developer/building-libyang.rst | 15 | ||||
| -rw-r--r-- | doc/developer/lists.rst | 61 | ||||
| -rw-r--r-- | doc/developer/process-architecture.rst | 4 | ||||
| -rw-r--r-- | doc/developer/topotests.rst | 2 |
4 files changed, 72 insertions, 10 deletions
diff --git a/doc/developer/building-libyang.rst b/doc/developer/building-libyang.rst index f50b8cf72d..5f82447d74 100644 --- a/doc/developer/building-libyang.rst +++ b/doc/developer/building-libyang.rst @@ -5,12 +5,16 @@ library. **Option 1: Binary Install** -The FRR project builds binary ``libyang`` packages, which we offer for download -`here <https://ci1.netdef.org/browse/LIBYANG-YANGRELEASE/latestSuccessful/artifact>`_. +The FRR project builds some binary ``libyang`` packages. + +RPM packages are at our `RPM repository <https://rpm.frrouting.org>`_. + +DEB packages are available as CI artifacts `here +<https://ci1.netdef.org/browse/LIBYANG-LY1REL-DEB10AMD64-4/artifact>`_. .. warning:: - ``libyang`` version 0.16.105 or newer is required to build FRR. + ``libyang`` version 1.0.184 or newer is required to build FRR. .. note:: @@ -50,8 +54,3 @@ The FRR project builds binary ``libyang`` packages, which we offer for download -D CMAKE_BUILD_TYPE:String="Release" .. make sudo make install - -When building ``libyang`` version ``0.16.x`` it's also necessary to pass the -``-DENABLE_CACHE=OFF`` parameter to ``cmake`` to work around a -`known bug <https://github.com/CESNET/libyang/issues/752>`_ in libyang. - diff --git a/doc/developer/lists.rst b/doc/developer/lists.rst index 9355141aa4..28b21533c0 100644 --- a/doc/developer/lists.rst +++ b/doc/developer/lists.rst @@ -497,6 +497,7 @@ API for hash tables Items that compare as equal cannot be inserted. Refer to the notes about sorted structures in the previous section. + .. c:function:: void Z_init_size(struct Z_head *, size_t size) Same as :c:func:`Z_init()` but preset the minimum hash table to @@ -506,6 +507,66 @@ Hash tables also support :c:func:`Z_add()` and :c:func:`Z_find()` with the same semantics as noted above. :c:func:`Z_find_gteq()` and :c:func:`Z_find_lt()` are **not** provided for hash tables. +Hash table invariants +^^^^^^^^^^^^^^^^^^^^^ + +There are several ways to injure yourself using the hash table API. + +First, note that there are two functions related to computing uniqueness of +objects inserted into the hash table. There is a hash function and a comparison +function. The hash function computes the hash of the object. Our hash table +implementation uses `chaining +<https://en.wikipedia.org/wiki/Hash_table#Separate_chaining_with_linked_lists>`_. +This means that your hash function does not have to be perfect; multiple +objects having the same computed hash will be placed into a linked list +corresponding to that key. The closer to perfect the hash function, the better +performance, as items will be more evenly distributed and the chain length will +not be long on any given lookup, minimizing the number of list operations +required to find the correct item. However, the comparison function *must* be +perfect, in the sense that any two unique items inserted into the hash table +must compare not equal. At insertion time, if you try to insert an item that +compares equal to an existing item the insertion will not happen and +``hash_get()`` will return the existing item. However, this invariant *must* be +maintained while the object is in the hash table. Suppose you insert items +``A`` and ``B`` into the hash table which both hash to the same value ``1234`` +but do not compare equal. They will be placed in a chain like so:: + + 1234 : A -> B + +Now suppose you do something like this elsewhere in the code:: + + *A = *B + +I.e. you copy all fields of ``B`` into ``A``, such that the comparison function +now says that they are equal based on their contents. At this point when you +look up ``B`` in the hash table, ``hash_get()`` will search the chain for the +first item that compares equal to ``B``, which will be ``A``. This leads to +insidious bugs. + +.. warning:: + + Never modify the values looked at by the comparison or hash functions after + inserting an item into a hash table. + +A similar situation can occur with the hash allocation function. ``hash_get()`` +accepts a function pointer that it will call to get the item that should be +inserted into the list if the provided item is not already present. There is a +builtin function, ``hash_alloc_intern``, that will simply return the item you +provided; if you always want to store the value you pass to ``hash_get`` you +should use this one. If you choose to provide a different one, that function +*must* return a new item that hashes and compares equal to the one you provided +to ``hash_get()``. If it does not the behavior of the hash table is undefined. + +.. warning:: + + Always make sure your hash allocation function returns a value that hashes + and compares equal to the item you provided to ``hash_get()``. + +Finally, if you maintain pointers to items you have inserted into a hash table, +then before deallocating them you must release them from the hash table. This +is basic memory management but worth repeating as bugs have arisen from failure +to do this. + API for heaps ------------- diff --git a/doc/developer/process-architecture.rst b/doc/developer/process-architecture.rst index 6e0eb68188..6a028d0000 100644 --- a/doc/developer/process-architecture.rst +++ b/doc/developer/process-architecture.rst @@ -94,7 +94,9 @@ irrelevant for the time being) for the specific type. For example, to add a thread_add_read(struct thread_master *master, int (*handler)(struct thread *), void *arg, int fd, struct thread **ref); The ``struct thread`` is then created and added to the appropriate internal -datastructure within the ``threadmaster``. +datastructure within the ``threadmaster``. Note that the ``READ`` and +``WRITE`` tasks are independent - a ``READ`` task only tests for +readability, for example. The Event Loop ^^^^^^^^^^^^^^ diff --git a/doc/developer/topotests.rst b/doc/developer/topotests.rst index b32f2bbf49..5486fd826d 100644 --- a/doc/developer/topotests.rst +++ b/doc/developer/topotests.rst @@ -722,7 +722,7 @@ Example: .. code:: py # For all registered routers, load the zebra configuration file - for rname, router in router_list.iteritems(): + for rname, router in router_list.items(): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, '{}/zebra.conf'.format(rname)) |
