001/** 002 * Copyright (c) 2011, The University of Southampton and the individual contributors. 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, 006 * are permitted provided that the following conditions are met: 007 * 008 * * Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * * Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * * Neither the name of the University of Southampton nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package org.openimaj.hadoop.tools.twitter.token.mode; 031 032import java.io.IOException; 033import java.io.PrintWriter; 034import java.util.HashMap; 035import java.util.Map; 036import java.util.Map.Entry; 037import java.util.Scanner; 038 039import org.apache.hadoop.mapreduce.Counter; 040import org.apache.hadoop.mapreduce.Counters; 041import org.openimaj.io.ReadWriteableASCII; 042 043/** 044 * A writeable hadoop {@link Counter} written using the enum <T> used with the counter 045 * @author Sina Samangooei (ss@ecs.soton.ac.uk) 046 * @param <T> the enum type 047 * 048 */ 049public abstract class WritableEnumCounter<T extends Enum<?>> implements ReadWriteableASCII { 050 private Map<T,Long> values; 051 /** 052 * initialise the values map 053 */ 054 public WritableEnumCounter() { 055 this.values = new HashMap<T, Long>(); 056 } 057 058 /** 059 * intitalise the global stats from some counters 060 * @param counters the counters to look for the enum types in 061 * @param enumType the enum types 062 */ 063 public WritableEnumCounter(Counters counters,T[] enumType) { 064 this(); 065 initCounts(enumType,counters); 066 } 067 068 private void initCounts(T[] values, Counters counters) { 069 for (T type : values) { 070 Counter c = counters.findCounter(type); 071 if(c!=null){ 072 this.values.put(type, c.getValue()); 073 } 074 } 075 } 076 077 /** 078 * @param type 079 * @param value 080 */ 081 public void setValue(T type, Long value) { 082 this.values.put(type, value); 083 } 084 085 @Override 086 public void readASCII(Scanner in) throws IOException { 087 if(!(in.hasNextLine())){ 088 System.out.println("WritableEnumCounter has no next line? weird?"); 089 return;// not sure why this would happen? 090 } 091 int count = Integer.parseInt(in.nextLine()); 092 for (int i = 0; i < count; i++) { 093 T type = valueOf(in.next()); 094 long value = Long.parseLong(in.next()); 095 this.values.put(type, value); 096 } 097 } 098 099 /** 100 * @param str 101 * @return The enum value of a given name 102 */ 103 public abstract T valueOf(String str); 104 105 @Override 106 public String asciiHeader() { 107 return "GLOBALSTATS\n"; 108 } 109 110 @Override 111 public void writeASCII(PrintWriter out) throws IOException { 112 out.println(this.values.size()); 113 for (Entry<T, Long> typevalue : this.values.entrySet()) { 114 out.println(typevalue.getKey() + " " + typevalue.getValue()); 115 } 116 } 117 118 /** 119 * @param type 120 * @return the value for the given type 121 */ 122 public long getValue(T type) { 123 if(values == null)return 0; 124 return this.values.get(type); 125 } 126 127 128}