def split_kbucket(self): """ Split the high half of this KBucket's range and assign it to a new KBucket. Relocate all relevant contacts to the new KBucket. Note: If multiple threads attempt to split the same KBucket, the operation may cause data corruption. Returns: The new KBucket, which covers the high part of the halved ID space. In addition to splitting the contacts, this method also splits the cache of the existing bucket, according to the guids. Then, it refills the contact lists from the caches. """ new_kbucket = super(CachingKBucket, self).split_kbucket() cache_self, cache_new = util.partition( self._replacement_cache, self.contact_in_range ) # Replacement caches are deques, so we can't directly assign # the values returned by partition. new_kbucket._replacement_cache.extend(cache_new) self._replacement_cache.clear() self._replacement_cache.extend(cache_self) self.fill_from_cache() new_kbucket.fill_from_cache() return new_kbucket
def split_kbucket(self): """ Split the high half of this KBucket's range and assign it to a new KBucket. Relocate all relevant contacts to the new KBucket. Note: If multiple threads attempt to split the same KBucket, data corruption may occur. Returns: The new KBucket, which covers the high part of the halved ID space. """ cur_range_size = self.range_max - self.range_min half_point = self.range_min + cur_range_size // 2 # Ensure no empty range is created. assert self.range_min < half_point < self.range_max # Make the instantiation dependent on the actual class, # for easy inheritance. new_kbucket = self.__class__(half_point, self.range_max) # Halve the ID space of the split KBucket. self.range_max = half_point # Split the contact list into two, according to the new ranges. self._contacts, new_kbucket._contacts = util.partition( self._contacts, self.contact_in_range ) return new_kbucket
def test_partition(self): sequence = list(range(6)) predicate = lambda n: n % 2 == 0 even, odd = util.partition(sequence, predicate) self.assertEqual(len(even) + len(odd), len(sequence)) for elem in sequence: if predicate(elem): self.assertIn(elem, even) else: self.assertIn(elem, odd)