Minimize synchronized blocks

This is a simple, obviously-correct improvement of scalability: we
reduce the sice of the synchronized sections such that they only cover
the datastore interaction.

Change-Id: I1c78804e6aed22aac73f67e9c5de43ff465c7836
Signed-off-by: Robert Varga <rovarga@cisco.com>
Topology manager: Pre-construct identifiers

Another obvious optimization: we pre-construct identifiers for later
use, so we do not end up performing "expensive" operations.

Change-Id: I2f611dca6fb37363799dfbffc72588391008c041
Signed-off-by: Robert Varga <rovarga@cisco.com>
Topology manager: get rid of sychronized sections

Instead of executing changes one by one, we aggregate them such that
ordering is preserved and we have one outstanding transaction at any
given moment. This is done by placing a queue between the notification
and data store, dispatched by a background thread. This should improve
scalability by reducing number of transactions and improving
notification thread concurrency.

Change-Id: Ica70971e4540a060491ac4c0b89a134984947fca
Signed-off-by: Robert Varga <rovarga@cisco.com>