ソースを参照

- TextEncoding: dependency on mazovia charset is optional
- AdvLogger: fixed small performance bug (use forcedLog)
- ListUtils#produce
- VirtualArray: new class
- VirtualList: serializabe
- VirtualList#produce
- MemoryChannel: new class

ranides atterwim 11 年 前
コミット
4e51398a23

+ 2 - 1
pom.xml

@@ -4,7 +4,7 @@
 
     <groupId>net.ranides</groupId>
     <artifactId>assira</artifactId>
-    <version>0.64.0</version>
+    <version>0.65.0</version>
     <packaging>jar</packaging>
 
     <name>assira</name>
@@ -179,6 +179,7 @@
             <groupId>eu.vitaliy</groupId>
             <artifactId>mazovia-charset</artifactId>
             <version>1.0</version>
+            <optional>true</optional>
         </dependency>
         <dependency>
             <groupId>joda-time</groupId>

+ 17 - 0
src/main/java/net/ranides/assira/collection/ListUtils.java

@@ -8,6 +8,7 @@
 package net.ranides.assira.collection;
 
 import java.util.*;
+import net.ranides.assira.generic.Function;
 
 /**
  * Operacje na listach.
@@ -321,6 +322,22 @@ public final class ListUtils {
     public static <T> List<T> constCopy(Collection<? extends T> values) {
         return new ConstList<>(values);
     }
+    
+    /**
+     * Tworzy nową listę o podanym rozmiarze. Elementy są generowane przez
+     * podaną funkcję w momencie tworzenia listy.
+     * @param <T>
+     * @param size
+     * @param function
+     * @return 
+     */
+    public static <T> List<T> produce(final int size, final Function<T, Integer> function) {
+        List<T> ret = new ArrayList<>(size);
+        for(int i=0; i<size; i++) {
+            ret.add(function.apply(i));
+        }
+        return ret;
+    }
 
     private static class ConstList<T> extends AbstractList<T> {
 

+ 30 - 0
src/main/java/net/ranides/assira/collection/list/VirtualArray.java

@@ -0,0 +1,30 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+
+package net.ranides.assira.collection.list;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @param <T>
+ */
+public abstract class VirtualArray<T> extends VirtualList<T> {
+    
+    private static final long serialVersionUID = 1L;
+    
+    private final int size;
+
+    public VirtualArray(int size) {
+        this.size = size;
+    }
+
+    @Override
+    public final int size() {
+        return size;
+    }
+    
+}

+ 27 - 1
src/main/java/net/ranides/assira/collection/list/VirtualList.java

@@ -7,7 +7,9 @@
 
 package net.ranides.assira.collection.list;
 
+import java.io.Serializable;
 import java.util.*;
+import net.ranides.assira.generic.Function;
 import net.ranides.assira.generic.ValueUtils;
 import net.ranides.assira.math.HashHelper;
 
@@ -28,7 +30,9 @@ import net.ranides.assira.math.HashHelper;
  * @param <T>
  * @author ranides
  */
-public abstract class VirtualList<T> implements List<T>, RandomAccess {
+public abstract class VirtualList<T> implements List<T>, RandomAccess, Serializable {
+    
+    private static final long serialVersionUID = 1L;
 
     private static final String MSG_IMMUTABLE_LIST = "Not supported by immutable virtual lists.";
 
@@ -369,4 +373,26 @@ public abstract class VirtualList<T> implements List<T>, RandomAccess {
     public static <Q> List<Q> subList(List<Q> list, int from, int to) {
         return (list instanceof RandomAccess) ? new RandomSubList<>(list, from, to) : new SubList<>(list, from, to);
     }
+    
+    /**
+     * Tworzy nową wirtualną listę o podanym rozmiarze. Elementy są generowane
+     * na żądanie.
+     * @param <Q>
+     * @param size
+     * @param function
+     * @return 
+     */
+    public static <Q> List<Q> produce(final int size, final Function<Q, Integer> function) {
+        return new VirtualList<Q>() {
+            @Override
+            public int size() {
+                return size;
+            }
+            @Override
+            public Q get(int index) {
+                return function.apply(index);
+            }
+        };
+    }
+    
 }

+ 120 - 0
src/main/java/net/ranides/assira/io/MemoryChannel.java

@@ -0,0 +1,120 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.io;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.ClosedChannelException;
+import java.nio.channels.SeekableByteChannel;
+import net.ranides.assira.collection.ArrayUtils;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public class MemoryChannel implements SeekableByteChannel {
+    
+    // @todo (assira # 3) MemoryChannel flexible implementation
+    // bytebuffer
+    // other buffers
+    // stringbuilder
+    // string
+    // byte[] array
+    // other primitive[] arrays
+    // non-seekable inputstream, outputstream, writer, reader
+    
+    private byte[] data;
+    private boolean opened;
+    private int position;
+
+    @SuppressWarnings("PMD.ArrayIsStoredDirectly")
+    public MemoryChannel(byte[] data) {
+        this.data = data;
+        this.opened = true;
+        this.position = 0;
+    }
+    
+    public MemoryChannel(int size) {
+        this(new byte[size]);
+    }
+
+    @Override
+    public int read(ByteBuffer dst) throws IOException {
+        opencheck();
+        int n = Math.min(dst.remaining(), data.length - position);
+        dst.put(data, position, n);
+        return n;
+    }
+
+    @Override
+    public int write(ByteBuffer src) throws IOException {
+        opencheck();
+        int n = src.remaining();
+        src.get(data, position, n);
+        return n;
+    }
+
+    @Override
+    public long position() throws IOException {
+        opencheck();
+        return position;
+    }
+
+    @Override
+    public SeekableByteChannel position(long newPosition) throws IOException {
+        opencheck();
+        if(newPosition<0) {
+            throw new IllegalArgumentException("position negative.");
+        }
+        if(newPosition > Integer.MAX_VALUE) {
+            throw new IOException("position limit.");
+        }
+        this.position = (int)newPosition;
+        return this;
+    }
+
+    @Override
+    public long size() throws IOException {
+        opencheck();
+        return data.length;
+    }
+
+    @Override
+    public SeekableByteChannel truncate(long size) throws IOException {
+        opencheck();
+        if(size <0) {
+            throw new IllegalArgumentException("size negative.");
+        }
+        if(size > Integer.MAX_VALUE) {
+            throw new IOException("size limit.");
+        }
+        if(size > data.length) {
+            data = ArrayUtils.clip(data, (int)size);
+        }
+        if(position > size) {
+            position = (int)size;
+        }
+        return this;
+    }
+
+    @Override
+    public boolean isOpen() {
+        return opened;
+    }
+
+    @Override
+    public void close() throws IOException {
+        opened = false;
+    }
+    
+    private void opencheck() throws ClosedChannelException {
+        if(!opened) {
+            throw new ClosedChannelException();
+        }
+    }
+    
+}

+ 16 - 1
src/main/java/net/ranides/assira/text/TextEncoding.java

@@ -9,6 +9,10 @@ package net.ranides.assira.text;
 
 import edu.umd.cs.findbugs.annotations.SuppressWarnings;
 import java.nio.charset.Charset;
+import java.nio.charset.UnsupportedCharsetException;
+import net.ranides.assira.annotations.Meta;
+import net.ranides.assira.trace.AdvLogger;
+import net.ranides.assira.trace.LoggerUtils;
 
 /**
  *
@@ -18,6 +22,8 @@ import java.nio.charset.Charset;
     "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD"
 })
 public final class TextEncoding {
+    
+    private static final AdvLogger LOGGER = LoggerUtils.getLogger();
 
     private TextEncoding() { }
 
@@ -39,7 +45,7 @@ public final class TextEncoding {
 
     public static final Charset NIO_PL_WINDOWS = Charset.forName("windows-1250");
 
-    public static final Charset NIO_MAZOVIA = Charset.forName("mazovia");
+    public static final Charset NIO_MAZOVIA = load("mazovia");
 
     public static final Charset NIO_DEFAULT = Charset.defaultCharset();
 
@@ -65,4 +71,13 @@ public final class TextEncoding {
 
     public static final String IO_DEFAULT = Charset.defaultCharset().name();
 
+    @Meta.Unsafe
+    private static Charset load(String name) {
+        try {
+            return Charset.forName(name);
+        } catch(UnsupportedCharsetException _cause) {
+            LOGGER.finfo("Optional support for charset '%s': DISABLED", name);
+            return null;
+        }
+    }
 }

+ 2 - 2
src/main/java/net/ranides/assira/trace/AdvLogger.java

@@ -62,7 +62,7 @@ public class AdvLogger extends org.apache.log4j.Logger {
     
     public void fwarn(String format, Object... args) {
         if( check(Level.WARN) ) {
-            log(ADV_FQCN, Level.WARN, Strings.sprintf(format, args), null);
+            forcedLog(ADV_FQCN, Level.WARN, Strings.sprintf(format, args), null);
         }
     }
     
@@ -100,7 +100,7 @@ public class AdvLogger extends org.apache.log4j.Logger {
     
     public void xwarn(String format, Throwable cause, Object... args) {
         if( check(Level.WARN) ) {
-            log(ADV_FQCN, Level.WARN, Strings.sprintf(format, args), cause);
+            forcedLog(ADV_FQCN, Level.WARN, Strings.sprintf(format, args), cause);
         }
     }
     

+ 0 - 1
src/test/java/net/ranides/assira/events/EventProactorTest.java

@@ -57,7 +57,6 @@ public class EventProactorTest {
 
     @Test
     public void testPropagation() {
-        // @todo (assira) EventProactor: unstable test of 
         HitMap hits = new HitMap();
         EventProactor unknown = EventProactor.newInstance("unknown", 2);
         EventProactor main = EventProactor.newInstance("name", 10);

+ 29 - 0
src/test/java/net/ranides/assira/text/TextEncodingTest.java

@@ -0,0 +1,29 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+
+package net.ranides.assira.text;
+
+import net.ranides.assira.trace.LoggerUtils;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public class TextEncodingTest {
+    
+    public TextEncodingTest() {
+        LoggerUtils.initTest();
+    }
+
+    @Test
+    public void testMazovia() {
+        assertNotNull(TextEncoding.NIO_MAZOVIA);
+    }
+    
+}