Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.programming > #3977 > unrolled thread
| Started by | Giuliano Bertoletti <gbe32241@libero.it> |
|---|---|
| First post | 2013-10-27 10:42 +0100 |
| Last post | 2013-10-27 12:22 -0700 |
| Articles | 3 — 3 participants |
Back to article view | Back to comp.programming
Detecting differences Giuliano Bertoletti <gbe32241@libero.it> - 2013-10-27 10:42 +0100
Re: Detecting differences Nobody <nobody@nowhere.com> - 2013-10-27 10:52 +0000
Re: Detecting differences malcolm.mclean5@btinternet.com - 2013-10-27 12:22 -0700
| From | Giuliano Bertoletti <gbe32241@libero.it> |
|---|---|
| Date | 2013-10-27 10:42 +0100 |
| Subject | Detecting differences |
| Message-ID | <526cdff8$0$23114$4fafbaef@reader2.news.tin.it> |
Hello, I'm trying to find an efficient algorithm to solve the following problem. I've two databases A and B that must be kept in sync. Both contain the same fixed number of elements (scores for tournament matches) and most of the time one is the mirror copy of the other. Sometimes however changes are applied either to A or B. On a regular basis the two DB communicate and in that occasion the algorithm should resync them. I've a way to resolve conflicts, so these are not a problem. However I wish to use as less bandwith as possible to sync them. Ideally if no changes are applied to either of them, the communication should be very short (in terms of bytes transfered) and in general proportional to the differences. The major problem is that the elements are many and small, so my idea would be to hash them (with a crypto algorithm as SHA1) in different groups and compare the hashes to detect changes. I could for example hash the entire sets, exchange the hashes and if they match I'm done. If they do not match however, I've to hunt down which elements have changed and I'm not sure which is the best way of grouping the items to miminize data exchanging. My idea is to organize hashes for n items in this way: Hash(0, n); Hash(0, n/2); Hash(n/2, n); Hash(0, n/4); Hash(n/4, n/2); Hash(n/2; 3n/4); Hash(3n/4; n); ... so if Hash(0, n) does not match, I send Hash(0, n/2); Hash(n/2, n); and possibly narrow down the mismatch set. Clearly if many differences have occurred, I could end up in a worse position than simply retransmitting the whole data. Does it makes sense? Is there a cleverer way? Giulio.
[toc] | [next] | [standalone]
| From | Nobody <nobody@nowhere.com> |
|---|---|
| Date | 2013-10-27 10:52 +0000 |
| Message-ID | <pan.2013.10.27.10.52.21.130000@nowhere.com> |
| In reply to | #3977 |
On Sun, 27 Oct 2013 10:42:15 +0100, Giuliano Bertoletti wrote: > Does it makes sense? Is there a cleverer way? rsync uses a single level; it selects a block size based upon the size of the file, then sends a list of hashes, one for each block. Any block with a hash mismatch is sent in its entirety. If you want to use multiple levels, the higher-level hashes should be calculated over the lower-level hashes rather than over the data. The optimum number of levels depends upon the probability of a difference. If differences are rare, then more levels will be more efficient. For a single difference, the asymptotically-optimal branching order is 3. If it wasn't constrained to be an integer, it would be e = 2.71828... (the value at which x/log(x) is a minimum). As differences become more common, you may as well skip the first few levels, as larger blocks will almost always have at least one difference. In short, there's no point in sending higher-level hashes which are likely to result in a mismatch. If differences are extremely common, then you'll end up sending the entire file anyhow and there's no point in sending any hashes.
[toc] | [prev] | [next] | [standalone]
| From | malcolm.mclean5@btinternet.com |
|---|---|
| Date | 2013-10-27 12:22 -0700 |
| Message-ID | <9bcb0a9d-424f-448a-bfa0-0a369ff2b5ed@googlegroups.com> |
| In reply to | #3977 |
On Sunday, October 27, 2013 9:42:15 AM UTC, Giuliano Bertoletti wrote: > > I'm trying to find an efficient algorithm to solve the following problem. > > I've two databases A and B that must be kept in sync. > > On a regular basis the two DB communicate and in that occasion the > algorithm should resync them. > > Ideally if no changes are applied to either of them, the communication > should be very short (in terms of bytes transfered) and in general > proportional to the differences. > Recursive hashing. Index the database along something, it doesn't matter what, as long as you can sensibly divide it into two roughly equal halves easily. Then has the who database, divide it, hash those halves, divide them and so on, until you reach single records. So if the databases are identical then the top level hashes are identical, and no data needs to be exchanged. If there is one change, you do effectively a binary search. If there are a few changes, it's several binary searches in parallel. If the whole database is different, you've added a factor of log N to your exchange time. Note for this to work you need to divide on A-M N-Z, etc, not "first N/2 entries, second N/2 entries". Otherwise a small change will have a cascading effect on the divisions.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.programming
csiph-web