/* (non-Javadoc) * @see org.archive.wayback.ResourceIndex#query(org.archive.wayback.core.WaybackRequest) */ public SearchResults query(WaybackRequest wbRequest) throws ResourceIndexNotAvailableException, ResourceNotInArchiveException, BadQueryException, AccessControlException { RangeGroup group = getRangeGroupForRequest(wbRequest); return group.query(wbRequest); }
@SuppressWarnings("unchecked") private void reloadMapFile() throws IOException { FlatFile ff = new FlatFile(mapPath); Iterator itr = ff.getSequentialIterator(); HashMap<String, RangeGroup> newGroupsMap = new HashMap<String, RangeGroup>(); HashMap<String, RangeGroup> oldGroupsMap = new HashMap<String, RangeGroup>(); if (groups != null) { for (int i = 0; i < groups.length; i++) { oldGroupsMap.put(groups[i].getName(), groups[i]); } } while (itr.hasNext()) { String line = (String) itr.next(); String[] parts = line.split(" "); if (parts.length < 3) { throw new IOException("Unparseable map line(" + line + ")"); } String name = parts[0]; String start = parts[1]; String end = parts[2]; int numMembers = parts.length - 3; String[] members = new String[numMembers]; for (int i = 0; i < numMembers; i++) { members[i] = parts[3 + i]; } RangeGroup group = null; if (oldGroupsMap.containsKey(name)) { group = oldGroupsMap.get(name); if (start.compareTo(group.getStart()) != 0) { throw new IOException("Change of start range in " + mapPath + " for range " + name); } if (end.compareTo(group.getEnd()) != 0) { throw new IOException("Change of end range in " + mapPath + " for range " + name); } } else { group = new RangeGroup(name, start, end); } group.setMembers(members); newGroupsMap.put(name, group); } Collection<RangeGroup> c = newGroupsMap.values(); RangeGroup[] newGroups = new RangeGroup[c.size()]; Iterator itrg = c.iterator(); for (int i = 0; itrg.hasNext(); i++) newGroups[i] = (RangeGroup) itrg.next(); // RangeGroup[] newGroups = (RangeGroup[]) c.toArray(); Arrays.sort(newGroups, comparator); groups = newGroups; LOGGER.info("Reloaded assignments from " + mapPath); }
/** * @author brad * @version $Date$, $Revision$ */ public class AlphaPartitionedIndex implements ResourceIndex { private static final Logger LOGGER = Logger.getLogger(AlphaPartitionedIndex.class.getName()); /** config name for path where map file is found */ public static String RANGE_MAP_PATH = "resourceindex.distributed.mappath"; /** config name for interval, in seconds, to check if the map file changed */ public static String RANGE_CHECK_INTERVAL = "resourceindex.distributed.checkinterval"; private static long MS_PER_SEC = 1000; private static long DEFAULT_CHECK_INTERVAL = 100; private long lastLoadStat = 0; private long nextCheck = 0; private long checkInterval = DEFAULT_CHECK_INTERVAL; private RangeGroup groups[] = null; private String mapPath; private static Comparator<RangeGroup> comparator = RangeGroup.getComparator(); private UrlCanonicalizer canonicalizer = null; public AlphaPartitionedIndex() { canonicalizer = new AggressiveUrlCanonicalizer(); } @SuppressWarnings("unchecked") private void reloadMapFile() throws IOException { FlatFile ff = new FlatFile(mapPath); Iterator itr = ff.getSequentialIterator(); HashMap<String, RangeGroup> newGroupsMap = new HashMap<String, RangeGroup>(); HashMap<String, RangeGroup> oldGroupsMap = new HashMap<String, RangeGroup>(); if (groups != null) { for (int i = 0; i < groups.length; i++) { oldGroupsMap.put(groups[i].getName(), groups[i]); } } while (itr.hasNext()) { String line = (String) itr.next(); String[] parts = line.split(" "); if (parts.length < 3) { throw new IOException("Unparseable map line(" + line + ")"); } String name = parts[0]; String start = parts[1]; String end = parts[2]; int numMembers = parts.length - 3; String[] members = new String[numMembers]; for (int i = 0; i < numMembers; i++) { members[i] = parts[3 + i]; } RangeGroup group = null; if (oldGroupsMap.containsKey(name)) { group = oldGroupsMap.get(name); if (start.compareTo(group.getStart()) != 0) { throw new IOException("Change of start range in " + mapPath + " for range " + name); } if (end.compareTo(group.getEnd()) != 0) { throw new IOException("Change of end range in " + mapPath + " for range " + name); } } else { group = new RangeGroup(name, start, end); } group.setMembers(members); newGroupsMap.put(name, group); } Collection<RangeGroup> c = newGroupsMap.values(); RangeGroup[] newGroups = new RangeGroup[c.size()]; Iterator itrg = c.iterator(); for (int i = 0; itrg.hasNext(); i++) newGroups[i] = (RangeGroup) itrg.next(); // RangeGroup[] newGroups = (RangeGroup[]) c.toArray(); Arrays.sort(newGroups, comparator); groups = newGroups; LOGGER.info("Reloaded assignments from " + mapPath); } private void checkMapFile() throws IOException { long now = System.currentTimeMillis(); if (nextCheck < now) { nextCheck = now + (checkInterval * MS_PER_SEC); File f = new File(mapPath); long curStat = f.lastModified(); if (curStat > lastLoadStat) { reloadMapFile(); lastLoadStat = curStat; } } } protected RangeGroup getRangeGroupForRequest(WaybackRequest wbRequest) throws BadQueryException, ResourceIndexNotAvailableException { String keyUrl; try { checkMapFile(); } catch (IOException e) { // TODO: this is too much error info if we're repeatedly failing.. e.printStackTrace(); throw new ResourceIndexNotAvailableException(e.getMessage()); } if (groups == null || groups.length == 0) { throw new ResourceIndexNotAvailableException("empty map file"); } String searchUrl = wbRequest.getRequestUrl(); if (searchUrl == null) { throw new BadQueryException("No " + WaybackRequest.REQUEST_URL + " specified"); } try { keyUrl = canonicalizer.urlStringToKey(searchUrl); } catch (URIException e) { throw new BadQueryException("invalid " + WaybackRequest.REQUEST_URL + " " + searchUrl); } RangeGroup dummy = new RangeGroup("", keyUrl, ""); int loc = Arrays.binarySearch(groups, dummy, comparator); if (loc < 0) { loc = (loc * -1) - 2; } LOGGER.info("Using group(" + groups[loc].getName() + ") for url (" + keyUrl + ")"); return groups[loc]; } /* (non-Javadoc) * @see org.archive.wayback.ResourceIndex#query(org.archive.wayback.core.WaybackRequest) */ public SearchResults query(WaybackRequest wbRequest) throws ResourceIndexNotAvailableException, ResourceNotInArchiveException, BadQueryException, AccessControlException { RangeGroup group = getRangeGroupForRequest(wbRequest); return group.query(wbRequest); } /** * @param url * @return canonicalized key version of url argument * @throws URIException */ public String canonicalize(final String url) throws URIException { return canonicalizer.urlStringToKey(url); } /** @return the checkInterval */ public long getCheckInterval() { return checkInterval; } /** @param checkInterval the checkInterval to set */ public void setCheckInterval(long checkInterval) { this.checkInterval = checkInterval; } /** @return the mapPath */ public String getMapPath() { return mapPath; } /** @param mapPath the mapPath to set */ public void setMapPath(String mapPath) { this.mapPath = mapPath; } public UrlCanonicalizer getCanonicalizer() { return canonicalizer; } public void setCanonicalizer(UrlCanonicalizer canonicalizer) { this.canonicalizer = canonicalizer; } public void shutdown() throws IOException { for (RangeGroup group : groups) { group.shutdown(); } } }
public void shutdown() throws IOException { for (RangeGroup group : groups) { group.shutdown(); } }