<s> from google . appengine . api import memcache <EOL> from google . appengine . ext import db <EOL> import random <EOL> class GeneralCounterShardConfig ( db . Model ) : <EOL> """<STR_LIT>""" <EOL> name = db . StringProperty ( required = True ) <EOL> num_shards = db . IntegerProperty ( required = True , default = <NUM_LIT:20> ) <EOL> class GeneralCounterShard ( db . Model ) : <EOL> """<STR_LIT>""" <EOL> name = db . StringProperty ( required = True ) <EOL> count = db . IntegerProperty ( required = True , default = <NUM_LIT:0> ) <EOL> def get_count ( name ) : <EOL> """<STR_LIT>""" <EOL> total = memcache . get ( name ) <EOL> if total is None : <EOL> total = <NUM_LIT:0> <EOL> for counter in GeneralCounterShard . all ( ) . filter ( '<STR_LIT>' , name ) : <EOL> total += counter . count <EOL> memcache . add ( name , str ( total ) , <NUM_LIT> ) <EOL> return total <EOL> def increment ( name ) : <EOL> """<STR_LIT>""" <EOL> config = GeneralCounterShardConfig . get_or_insert ( name , name = name ) <EOL> def txn ( ) : <EOL> index = random . randint ( <NUM_LIT:0> , config . num_shards - <NUM_LIT:1> ) <EOL> shard_name = name + str ( index ) <EOL> counter = GeneralCounterShard . get_by_key_name ( shard_name ) <EOL> if counter is None : <EOL> counter = GeneralCounterShard ( key_name = shard_name , name = name ) <EOL> counter . count += <NUM_LIT:1> <EOL> counter . put ( ) <EOL> db . run_in_transaction ( txn ) <EOL> memcache . incr ( name ) <EOL> def increase_shards ( name , num ) : <EOL> """<STR_LIT>""" <EOL> config = GeneralCounterShardConfig . get_or_insert ( name , name = name ) <EOL> def txn ( ) : <EOL> if config . num_shards < num : <EOL> config . num_shards = num <EOL> config . put ( ) <EOL> db . run_in_transaction ( txn ) </s>
