package net.pixelcop.sewer.source;

import net.pixelcop.sewer.ByteArrayEvent;
import net.pixelcop.sewer.Event;

import org.apache.hadoop.io.Text;
import org.eclipse.jetty.http.HttpHeaders;
import org.eclipse.jetty.server.Request;

public class AccessLogExtractor {

  private static final byte[] TAB = new String("\t").getBytes();
  private static final byte[] S_204 = new String("204").getBytes();

  public static Event extractByteArrayEvent(Request baseRequest) {

    Text text = new Text();

    // 9 vals
    // ${time_nsecs},${ip_remote},"${http_host}","${request}","${query_string}"
    // ${status},"${http_referrer}","${http_user_agent}","${http_cookie}"

    // time_nsecs
    // we currently want ns, but we might be better off with
    // using the already stored ms in baseRequest.getTimeStamp()
    append(text, Long.toString(System.nanoTime()));

    // ip_remote
    String addr = baseRequest.getHeader(HttpHeaders.X_FORWARDED_FOR);
    if (addr == null) {
        addr = baseRequest.getRemoteAddr();
    }
    append(text, addr);

    // http_host
    append(text, baseRequest.getServerName());

    // request
    append(text, baseRequest.getRequestURI());

    // query_string
    append(text, baseRequest.getQueryString());

    // status
    text.append(S_204, 0, 3);
    text.append(TAB, 0, 1);

    // http_referrer
    append(text, baseRequest.getHeader(HttpHeaders.REFERER));

    // http_user_agent
    append(text, baseRequest.getHeader(HttpHeaders.USER_AGENT));

    // http_cookie
    append(text, baseRequest.getHeader(HttpHeaders.COOKIE), true);

    return new ByteArrayEvent(text.toString().getBytes());
  }

  private static void append(Text text, String val) {
    append(text, val, false);
  }

  private static void append(Text text, String val, boolean lastVal) {
    if (val != null) {
      text.append(val.getBytes(), 0, val.length());
    }
    text.append(TAB, 0, 1);
  }

}

@@ -393,16 +393,183 @@
 tes();%0A%0A
+  private static final ThreadLocal%3CText%3E textLocal = new ThreadLocal%3CText%3E() %7B%0A    protected Text initialValue() %7B%0A      return new Text(new byte%5B1024%5D);%0A    %7D;%0A  %7D;%0A%0A
   public
@@ -644,24 +644,47 @@
  text = 
-new Text
+textLocal.get();%0A    text.clear
 ();%0A%0A   

use a ThreadLocal<Text>; should be marginally faster, less GC load