コード例 #1
0
    def testHashSpaceRepeatableLookups(self):
        hashSpace = Flexihash()
        for i in range(1, 10):
            hashSpace.addTarget("target" + str(i))

        self.assertEqual(hashSpace.lookup('t1'), hashSpace.lookup('t1'))
        self.assertEqual(hashSpace.lookup('t2'), hashSpace.lookup('t2'))
コード例 #2
0
    def testAddTargetAndGetAllTargets(self):
        hashSpace = Flexihash()
        hashSpace \
            .addTarget('t-a') \
            .addTarget('t-b') \
            .addTarget('t-c')

        self.assertEqual(hashSpace.getAllTargets(), ['t-a', 't-b', 't-c'])
コード例 #3
0
    def testAddTargetAndGetAllTargets(self):
        hashSpace = Flexihash()
        hashSpace \
            .addTarget('t-a') \
            .addTarget('t-b') \
            .addTarget('t-c')

        self.assertEqual(hashSpace.getAllTargets(), ['t-a', 't-b', 't-c'])
コード例 #4
0
    def testHashSpaceLookupsAreValidTargets(self):
        targets = ["target" + str(i) for i in range(1, 10)]

        hashSpace = Flexihash()
        hashSpace.addTargets(targets)

        for i in range(1, 10):
            self.assertTrue(hashSpace.lookup("r"+str(i)) in targets, 'target must be in list of targets')
コード例 #5
0
    def testGetMultipleTargetsWithOnlyOneTarget(self):
        hashSpace = Flexihash()
        hashSpace.addTarget("single-target")

        targets = hashSpace.lookupList('resource', 2)

        self.assertIsInstance(targets, list)
        self.assertEqual(len(targets), 1)
        self.assertEqual(targets[0], 'single-target')
コード例 #6
0
    def testGetMultipleTargetsWithOnlyOneTarget(self):
        hashSpace = Flexihash()
        hashSpace.addTarget("single-target")

        targets = hashSpace.lookupList('resource', 2)

        self.assertIsInstance(targets, list)
        self.assertEqual(len(targets), 1)
        self.assertEqual(targets[0], 'single-target')
コード例 #7
0
    def testGetMultipleTargets(self):
        hashSpace = Flexihash()
        for i in range(1, 10):
            hashSpace.addTarget("target" + str(i))

        targets = hashSpace.lookupList('resource', 2)

        self.assertIsInstance(targets, list)
        self.assertEqual(len(targets), 2)
        self.assertNotEqual(targets[0], targets[1])
コード例 #8
0
    def testGetMoreTargetsThanExist(self):
        hashSpace = Flexihash()
        hashSpace.addTarget("target1")
        hashSpace.addTarget("target2")

        targets = hashSpace.lookupList('resource', 4)

        self.assertIsInstance(targets, list)
        self.assertEqual(len(targets), 2)
        self.assertNotEqual(targets[0], targets[1])
コード例 #9
0
    def testGetMoreTargetsThanExist(self):
        hashSpace = Flexihash()
        hashSpace.addTarget("target1")
        hashSpace.addTarget("target2")

        targets = hashSpace.lookupList('resource', 4)

        self.assertIsInstance(targets, list)
        self.assertEqual(len(targets), 2)
        self.assertNotEqual(targets[0], targets[1])
コード例 #10
0
    def testGetMultipleTargets(self):
        hashSpace = Flexihash()
        for i in range(1, 10):
            hashSpace.addTarget("target" + str(i))

        targets = hashSpace.lookupList('resource', 2)

        self.assertIsInstance(targets, list)
        self.assertEqual(len(targets), 2)
        self.assertNotEqual(targets[0], targets[1])
コード例 #11
0
    def testHashSpaceLookupsAreValidTargets(self):
        targets = ["target" + str(i) for i in range(1, 10)]

        hashSpace = Flexihash()
        hashSpace.addTargets(targets)

        for i in range(1, 10):
            self.assertTrue(
                hashSpace.lookup("r" + str(i)) in targets,
                'target must be in list of targets')
コード例 #12
0
 def testLookupListReturnsWithShortListIfAllTargetsUsed(self):
     hashSpace = Flexihash()
     # both have CRC32 of 1253617450
     hashSpace.addTarget("x").addTarget("y")     # make the list non-empty, non-one-value, to avoid shortcuts
     hashSpace.addTarget("80726")                # add a value
     hashSpace.addTarget("14746907")             # add a different value with the same hash, to clobber the first
     hashSpace.removeTarget("14746907")          # remove the fourth value; with the third clobbered, only X and Y are left
     result = hashSpace.lookupList('test', 3)    # try to get 3 results, our target list is X, Y, 80726
     self.assertEqual(len(result), 2)            # but 80726 isn't reachable since it was clobbered
     self.assertIn("x", result)                  # all that's left is x
     self.assertIn("y", result)                  # and y
コード例 #13
0
def balance(tmpl):
    """
    >>> balance("http://mirror-{001,002,003}.foo.com/filename01.png")
    'http://mirror-002.foo.com/filename01.png'
    >>> balance("http://mirror-{001,002,003}.foo.com/filename02.png")
    'http://mirror-001.foo.com/filename02.png'
    >>> balance("http://mirror-{001,002,003}.foo.com/filename03.png")
    'http://mirror-002.foo.com/filename03.png'
    >>> balance("http://mirror-{001,002,003}.foo.com/filename04.png")
    'http://mirror-002.foo.com/filename04.png'
    """
    matches = _balance_pattern.match(tmpl)
    if matches:
        pre = matches.group(1)
        opts = matches.group(2)
        post = matches.group(3)

        if opts not in _balancers:
            _balancers[opts] = Flexihash()
            opt_list = opts.split(",")
            for opt in opt_list:
                if "=" in opt:
                    val, weight = opt.split("=")
                else:
                    val, weight = opt, 1
                _balancers[opts].addTarget(val, int(weight))

        choice = _balancers[opts].lookup(
            (pre + post).encode("ascii", "replace"))
        return pre + choice + post
    return tmpl
コード例 #14
0
    def test_basic(self):
        fh = Flexihash()

        fh.addTarget("a")
        fh.addTarget("b")
        fh.addTarget("c")

        self.assertEqual(fh.lookup("1"), "a")
        self.assertEqual(fh.lookup("2"), "b")
        self.assertEqual(fh.lookup("3"), "a")
コード例 #15
0
    def testHashSpaceConsistentLookupsWithNewInstance(self):
        hashSpace1 = Flexihash()
        for i in range(1, 10):
            hashSpace1.addTarget("target" + str(i))

        results1 = []
        for i in range(1, 100):
            results1.append(hashSpace1.lookup("t" + str(i)))

        hashSpace2 = Flexihash()
        for i in range(1, 10):
            hashSpace2.addTarget("target" + str(i))

        results2 = []
        for i in range(1, 100):
            results2.append(hashSpace2.lookup("t" + str(i)))

        self.assertEqual(results1, results2)
コード例 #16
0
    def testGetMultipleTargetsWithoutNeedingToLoopToStart(self):
        mockHasher = MockHasher()
        hashSpace = Flexihash(mockHasher, 1)

        mockHasher.setHashValue(10)
        hashSpace.addTarget("t1")

        mockHasher.setHashValue(20)
        hashSpace.addTarget("t2")

        mockHasher.setHashValue(30)
        hashSpace.addTarget("t3")

        mockHasher.setHashValue(15)
        targets = hashSpace.lookupList('resource', 2)

        self.assertEqual(targets, ['t2', 't3'])
コード例 #17
0
    def testHashSpaceRepeatableLookups(self):
        hashSpace = Flexihash()
        for i in range(1, 10):
            hashSpace.addTarget("target" + str(i))

        self.assertEqual(hashSpace.lookup('t1'), hashSpace.lookup('t1'))
        self.assertEqual(hashSpace.lookup('t2'), hashSpace.lookup('t2'))
コード例 #18
0
    def testHashSpaceConsistentLookupsAfterAddingAndRemoving(self):
        hashSpace = Flexihash()
        for i in range(1, 10):
            hashSpace.addTarget("target" + str(i))

        results1 = []
        for i in range(1, 100):
            results1.append(hashSpace.lookup("t"+str(i)))

        hashSpace \
            .addTarget('new-target') \
            .removeTarget('new-target') \
            .addTarget('new-target') \
            .removeTarget('new-target')

        results2 = []
        for i in range(1, 100):
            results2.append(hashSpace.lookup("t"+str(i)))

        # This is probably optimistic, as adding/removing a target may
        # clobber existing targets and is not expected to restore them.
        self.assertEqual(results1, results2)
コード例 #19
0
    def testGetMultipleTargetsWithoutNeedingToLoopToStart(self):
        mockHasher = MockHasher()
        hashSpace = Flexihash(mockHasher, 1)

        mockHasher.setHashValue(10)
        hashSpace.addTarget("t1")

        mockHasher.setHashValue(20)
        hashSpace.addTarget("t2")

        mockHasher.setHashValue(30)
        hashSpace.addTarget("t3")

        mockHasher.setHashValue(15)
        targets = hashSpace.lookupList('resource', 2)

        self.assertEqual(targets, ['t2', 't3'])
コード例 #20
0
    def testHashSpaceConsistentLookupsWithNewInstance(self):
        hashSpace1 = Flexihash()
        for i in range(1, 10):
            hashSpace1.addTarget("target" + str(i))

        results1 = []
        for i in range(1, 100):
            results1.append(hashSpace1.lookup("t"+str(i)))

        hashSpace2 = Flexihash()
        for i in range(1, 10):
            hashSpace2.addTarget("target" + str(i))

        results2 = []
        for i in range(1, 100):
            results2.append(hashSpace2.lookup("t"+str(i)))

        self.assertEqual(results1, results2)
コード例 #21
0
    def testHashSpaceConsistentLookupsAfterAddingAndRemoving(self):
        hashSpace = Flexihash()
        for i in range(1, 10):
            hashSpace.addTarget("target" + str(i))

        results1 = []
        for i in range(1, 100):
            results1.append(hashSpace.lookup("t" + str(i)))

        hashSpace \
            .addTarget('new-target') \
            .removeTarget('new-target') \
            .addTarget('new-target') \
            .removeTarget('new-target')

        results2 = []
        for i in range(1, 100):
            results2.append(hashSpace.lookup("t" + str(i)))

        # This is probably optimistic, as adding/removing a target may
        # clobber existing targets and is not expected to restore them.
        self.assertEqual(results1, results2)
コード例 #22
0
 def testLookupThrowsExceptionOnEmpty(self):
     hashSpace = Flexihash()
     self.assertRaises(Flexihash_Exception, hashSpace.lookup, 'test')
コード例 #23
0
 def testLookupListReturnsWithShortListIfAllTargetsUsed(self):
     hashSpace = Flexihash()
     # both have CRC32 of 1253617450
     hashSpace.addTarget("x").addTarget(
         "y")  # make the list non-empty, non-one-value, to avoid shortcuts
     hashSpace.addTarget("80726")  # add a value
     hashSpace.addTarget(
         "14746907"
     )  # add a different value with the same hash, to clobber the first
     hashSpace.removeTarget(
         "14746907"
     )  # remove the fourth value; with the third clobbered, only X and Y are left
     result = hashSpace.lookupList(
         'test', 3)  # try to get 3 results, our target list is X, Y, 80726
     self.assertEqual(len(result),
                      2)  # but 80726 isn't reachable since it was clobbered
     self.assertIn("x", result)  # all that's left is x
     self.assertIn("y", result)  # and y
コード例 #24
0
 def testLookupListThrowsExceptionOnZero(self):
     hashSpace = Flexihash()
     self.assertRaises(Flexihash_Exception, hashSpace.lookupList, 'test', 0)
コード例 #25
0
    def testGetMultipleTargetsNeedingToLoopToStart(self):
        mockHasher = MockHasher()
        hashSpace = Flexihash(mockHasher, 1)

        mockHasher.setHashValue(10)
        hashSpace.addTarget("t1")

        mockHasher.setHashValue(20)
        hashSpace.addTarget("t2")

        mockHasher.setHashValue(30)
        hashSpace.addTarget("t3")

        mockHasher.setHashValue(40)
        hashSpace.addTarget("t4")

        mockHasher.setHashValue(50)
        hashSpace.addTarget("t5")

        mockHasher.setHashValue(35)
        targets = hashSpace.lookupList('resource', 4)

        self.assertEqual(targets, ['t4', 't5', 't1', 't2'])
コード例 #26
0
    def testAddTargetsAndGetAllTargets(self):
        targets = ['t-a', 't-b', 't-c']

        hashSpace = Flexihash()
        hashSpace.addTargets(targets)
        self.assertEqual(hashSpace.getAllTargets(), targets)
コード例 #27
0
 def testGetAllTargetsEmpty(self):
     hashSpace = Flexihash()
     self.assertEqual(hashSpace.getAllTargets(), [])
コード例 #28
0
 def testAddTargetThrowsExceptionOnDuplicateTarget(self):
     hashSpace = Flexihash()
     hashSpace.addTarget('t-a')
     self.assertRaises(FlexihashException, hashSpace.addTarget, 't-a')
コード例 #29
0
    def testAddTargetsAndGetAllTargets(self):
        targets = ['t-a', 't-b', 't-c']

        hashSpace = Flexihash()
        hashSpace.addTargets(targets)
        self.assertEqual(hashSpace.getAllTargets(), targets)
コード例 #30
0
    def testFallbackPrecedenceWhenServerRemoved(self):
        mockHasher = MockHasher()
        hashSpace = Flexihash(mockHasher, 1)

        mockHasher.setHashValue(10)
        hashSpace.addTarget("t1")

        mockHasher.setHashValue(20)
        hashSpace.addTarget("t2")

        mockHasher.setHashValue(30)
        hashSpace.addTarget("t3")

        mockHasher.setHashValue(15)

        self.assertEqual(hashSpace.lookup('resource'), 't2')
        self.assertEqual(
            hashSpace.lookupList('resource', 3),
            ['t2', 't3', 't1']
        )

        hashSpace.removeTarget('t2')

        self.assertEqual(hashSpace.lookup('resource'), 't3')
        self.assertEqual(
            hashSpace.lookupList('resource', 3),
            ['t3', 't1']
        )

        hashSpace.removeTarget('t3')

        self.assertEqual(hashSpace.lookup('resource'), 't1')
        self.assertEqual(
            hashSpace.lookupList('resource', 3),
            ['t1']
        )
コード例 #31
0
    def testGetMultipleTargetsNeedingToLoopToStart(self):
        mockHasher = MockHasher()
        hashSpace = Flexihash(mockHasher, 1)

        mockHasher.setHashValue(10)
        hashSpace.addTarget("t1")

        mockHasher.setHashValue(20)
        hashSpace.addTarget("t2")

        mockHasher.setHashValue(30)
        hashSpace.addTarget("t3")

        mockHasher.setHashValue(40)
        hashSpace.addTarget("t4")

        mockHasher.setHashValue(50)
        hashSpace.addTarget("t5")

        mockHasher.setHashValue(35)
        targets = hashSpace.lookupList('resource', 4)

        self.assertEqual(targets, ['t4', 't5', 't1', 't2'])
コード例 #32
0
 def testRemoveTargetFailsOnMissingTarget(self):
     hashSpace = Flexihash()
     self.assertRaises(Flexihash_Exception, hashSpace.removeTarget,
                       'not-there')
コード例 #33
0
    def testFallbackPrecedenceWhenServerRemoved(self):
        mockHasher = MockHasher()
        hashSpace = Flexihash(mockHasher, 1)

        mockHasher.setHashValue(10)
        hashSpace.addTarget("t1")

        mockHasher.setHashValue(20)
        hashSpace.addTarget("t2")

        mockHasher.setHashValue(30)
        hashSpace.addTarget("t3")

        mockHasher.setHashValue(15)

        self.assertEqual(hashSpace.lookup('resource'), 't2')
        self.assertEqual(hashSpace.lookupList('resource', 3),
                         ['t2', 't3', 't1'])

        hashSpace.removeTarget('t2')

        self.assertEqual(hashSpace.lookup('resource'), 't3')
        self.assertEqual(hashSpace.lookupList('resource', 3), ['t3', 't1'])

        hashSpace.removeTarget('t3')

        self.assertEqual(hashSpace.lookup('resource'), 't1')
        self.assertEqual(hashSpace.lookupList('resource', 3), ['t1'])
コード例 #34
0
 def testGetAllTargetsEmpty(self):
     hashSpace = Flexihash()
     self.assertEqual(hashSpace.getAllTargets(), [])
コード例 #35
0
 def testAddTargetThrowsExceptionOnDuplicateTarget(self):
     hashSpace = Flexihash()
     hashSpace.addTarget('t-a')
     self.assertRaises(Flexihash_Exception, hashSpace.addTarget, 't-a')