Advertisement
Guest User

SlidingWindowMap: Beust Challenge

a guest
Sep 4th, 2012
28
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 2.51 KB | None | 0 0
  1. /**
  2.  * Copyright (c) 2011, Datacard Group, Minnetonka, MN. Do NOT copy or include without permission!
  3.  */
  4. package com.xsm.beustchallenge.slidingwindowmap;
  5.  
  6. import java.util.Date;
  7. import java.util.Iterator;
  8. import java.util.LinkedList;
  9. import java.util.List;
  10. import java.util.Set;
  11.  
  12. /**
  13.  * Solving for Beust Challenge: Sliding Window Map
  14.  * http://beust.com/weblog/2012/09/02/coding-challenge-a-sliding-window-map/
  15.  *
  16.  * @author Sony Mathew
  17.  */
  18. public class SlidingWindowMap {
  19.    
  20.     private final Set<String> keys;
  21.     private final int maxCount;
  22.     private final long maxPeriodMs;
  23.    
  24.     private List<KeyTrack> keyTracks = new LinkedList<>();
  25.    
  26.     /**
  27.      * author Sony Mathew
  28.      */
  29.     public SlidingWindowMap(Set<String> keys, int maxCount, long maxPeriodMs) {
  30.         this.keys = keys;
  31.         this.maxCount = maxCount;
  32.         this.maxPeriodMs = maxPeriodMs;
  33.        
  34.         for(String key : this.keys) {
  35.             keyTracks.add(new KeyTrack(key));
  36.         }
  37.     }
  38.  
  39.     /**
  40.      * @return a key that has been used less than `maxCount` times during the
  41.      *         past `maxPeriodMs` milliseconds or null if no such key exists.
  42.      */
  43.     public synchronized String getNextKey() {
  44.         List<KeyTrack> keyTracksUsedUp = new LinkedList<>();
  45.         try {
  46.             Iterator<KeyTrack> keyTrackIter = keyTracks.iterator();
  47.             while(keyTrackIter.hasNext()) {
  48.                 KeyTrack keyTrack = keyTrackIter.next();
  49.                 String key = keyTrack.useKey();
  50.                 if (key != null) {                                         
  51.                     return key;
  52.                 }else{
  53.                     keyTrackIter.remove();
  54.                     keyTracksUsedUp.add(keyTrack);
  55.                 }
  56.             }
  57.             return null; //no keys found, all used up.
  58.         }finally{
  59.             //put used-up keys back at the end.
  60.             for(KeyTrack keyTrackUsedUp : keyTracksUsedUp) {
  61.                 keyTracks.add(keyTrackUsedUp);
  62.             }
  63.         }
  64.     }
  65.    
  66.     /**
  67.      * Tracks a key's use.
  68.      *
  69.      * @author Sony Mathew
  70.      */
  71.     class KeyTrack {
  72.         final String key;
  73.         final List<Date> useTimes = new LinkedList<>();
  74.        
  75.         KeyTrack(String key) {
  76.             this.key = key;
  77.         }
  78.        
  79.         /**
  80.          * @return : key if it can be used, else null.
  81.          * author Sony Mathew
  82.          */
  83.         String useKey() {
  84.             Date now = new Date();
  85.            
  86.             //Remove all old use times.
  87.             Iterator<Date> useTimeIter = useTimes.iterator();
  88.             while (useTimeIter.hasNext()) {
  89.                 Date useTime = useTimeIter.next();
  90.                 long usePeriod = now.getTime()-useTime.getTime();
  91.                 if (usePeriod>maxPeriodMs) {
  92.                     useTimeIter.remove(); //no longer countable, past max period.
  93.                 }
  94.             }
  95.            
  96.             if (useTimes.size() < maxCount) {
  97.                 useTimes.add(now);
  98.                 return key;            
  99.             }
  100.            
  101.             return null;
  102.         }
  103.     }  
  104. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement