Clearly, the one-to-one and the many-to-one topology are abundantly more common in the context of day-to-day commercial applications than the many-to-many topology. Moreover, the many-to-many topology can be indirectly (but inefficiently) achieved by designating one device as a server and stipulating that the other devices synchronize with that server and hence indirectly synchronize with each other via that server. Implementing the many-to-one topology (which includes the one-to-one model) is conceptually simpler and the resulting implementations are orders of magnitude simpler than the ones that support many-to-many topology. In the many-to-many model, complex data structures such as "version vectors" need to be associated with data items to correctly synchronize data. The many-to-many model is also especially stubborn for the purposes of accounting and failure recovery.
For the above reasons, SyncML is optimized for the many-to-one topology. It allows the exchange of datastore sync anchors (see Chapter 5) in the beginning of a synchronization, which indicate the last "timestamp" at which the two computers synchronized. The timestamp could be an actual time value or a logical counter. Based on the exchanged sync anchor values, the associated sync engines could use simple data structures such as change logs (see Chapter 4) to determine the changes made to data items since the last instance of synchronization. SyncML, however, allows many-to-many synchronization. It allows each data item to have an associated version which could actually be a version vector required for many-to-many synchronization. It also does not specify the format of the sync anchor explicitly and therefore that could also be a version vector. Furthermore, a SyncML device can play dual roles of a server or a client.