소스 검색

add simple map stream capability

kimchy 15 년 전
부모
커밋
9a80fedf52

+ 1 - 0
.idea/dictionaries/kimchy.xml

@@ -130,6 +130,7 @@
       <w>startup</w>
       <w>stopwords</w>
       <w>streamable</w>
+      <w>streamables</w>
       <w>struct</w>
       <w>substring</w>
       <w>successul</w>

+ 151 - 0
modules/elasticsearch/src/main/java/org/elasticsearch/common/io/stream/Streamables.java

@@ -0,0 +1,151 @@
+/*
+ * Licensed to Elastic Search and Shay Banon under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. Elastic Search licenses this
+ * file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.common.io.stream;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author kimchy (shay.banon)
+ */
+public class Streamables {
+
+    public static Map<String, Object> readMap(StreamInput in) throws IOException {
+        int size = in.readVInt();
+        Map<String, Object> map = new HashMap<String, Object>(size);
+        for (int i = 0; i < size; i++) {
+            map.put(in.readUTF(), readMapValue(in));
+        }
+        return map;
+    }
+
+    public static Object readMapValue(StreamInput in) throws IOException {
+        byte type = in.readByte();
+        if (type == -1) {
+            return null;
+        } else if (type == 0) {
+            return in.readUTF();
+        } else if (type == 1) {
+            return in.readInt();
+        } else if (type == 2) {
+            return in.readLong();
+        } else if (type == 3) {
+            return in.readFloat();
+        } else if (type == 4) {
+            return in.readDouble();
+        } else if (type == 5) {
+            return in.readBoolean();
+        } else if (type == 6) {
+            int bytesSize = in.readVInt();
+            byte[] value = new byte[bytesSize];
+            in.readFully(value);
+            return value;
+        } else if (type == 7) {
+            int size = in.readVInt();
+            List list = new ArrayList(size);
+            for (int i = 0; i < size; i++) {
+                list.add(readMapValue(in));
+            }
+            return list;
+        } else if (type == 8) {
+            int size = in.readVInt();
+            Object[] list = new Object[size];
+            for (int i = 0; i < size; i++) {
+                list[i] = readMapValue(in);
+            }
+            return list;
+        } else if (type == 9) {
+            int size = in.readVInt();
+            Map map = new HashMap(size);
+            for (int i = 0; i < size; i++) {
+                map.put(in.readUTF(), readMapValue(in));
+            }
+            return map;
+        } else {
+            throw new IOException("Can't read unknown type [" + type + "]");
+        }
+    }
+
+    public static void writeMap(StreamOutput out, Map<String, Object> map) throws IOException {
+        out.writeVInt(map.size());
+        for (Map.Entry<String, Object> entry : map.entrySet()) {
+            out.writeUTF(entry.getKey());
+            writeMapValue(out, entry.getValue());
+        }
+    }
+
+    private static void writeMapValue(StreamOutput out, Object value) throws IOException {
+        if (value == null) {
+            out.writeByte((byte) -1);
+            return;
+        }
+        Class type = value.getClass();
+        if (type == String.class) {
+            out.writeByte((byte) 0);
+            out.writeUTF((String) value);
+        } else if (type == Integer.class) {
+            out.writeByte((byte) 1);
+            out.writeInt((Integer) value);
+        } else if (type == Long.class) {
+            out.writeByte((byte) 2);
+            out.writeLong((Long) value);
+        } else if (type == Float.class) {
+            out.writeByte((byte) 3);
+            out.writeFloat((Float) value);
+        } else if (type == Double.class) {
+            out.writeByte((byte) 4);
+            out.writeDouble((Double) value);
+        } else if (type == Boolean.class) {
+            out.writeByte((byte) 5);
+            out.writeBoolean((Boolean) value);
+        } else if (type == byte[].class) {
+            out.writeByte((byte) 6);
+            out.writeVInt(((byte[]) value).length);
+            out.writeBytes(((byte[]) value));
+        } else if (value instanceof List) {
+            out.writeByte((byte) 7);
+            List list = (List) value;
+            out.writeVInt(list.size());
+            for (Object o : list) {
+                writeMapValue(out, o);
+            }
+        } else if (value instanceof Object[]) {
+            out.writeByte((byte) 8);
+            Object[] list = (Object[]) value;
+            out.writeVInt(list.length);
+            for (Object o : list) {
+                writeMapValue(out, o);
+            }
+        } else if (value instanceof Map) {
+            out.writeByte((byte) 9);
+            Map<String, Object> map = (Map<String, Object>) value;
+            out.writeVInt(map.size());
+            for (Map.Entry<String, Object> entry : map.entrySet()) {
+                out.writeUTF(entry.getKey());
+                writeMapValue(out, entry.getValue());
+            }
+        } else {
+            throw new IOException("Can't write type [" + type + "]");
+        }
+    }
+}

+ 16 - 2
modules/elasticsearch/src/main/java/org/elasticsearch/common/lucene/Lucene.java

@@ -310,7 +310,14 @@ public class Lucene {
             return list;
         } else if (type == 8) {
             int size = in.readVInt();
-            Map map = new HashMap();
+            Object[] list = new Object[size];
+            for (int i = 0; i < size; i++) {
+                list[i] = readFieldValue(in);
+            }
+            return list;
+        } else if (type == 9) {
+            int size = in.readVInt();
+            Map map = new HashMap(size);
             for (int i = 0; i < size; i++) {
                 map.put(in.readUTF(), readFieldValue(in));
             }
@@ -355,8 +362,15 @@ public class Lucene {
             for (Object o : list) {
                 writeFieldValue(out, o);
             }
-        } else if (value instanceof Map) {
+        } else if (value instanceof Object[]) {
             out.writeByte((byte) 8);
+            Object[] list = (Object[]) value;
+            out.writeVInt(list.length);
+            for (Object o : list) {
+                writeFieldValue(out, o);
+            }
+        } else if (value instanceof Map) {
+            out.writeByte((byte) 9);
             Map<String, Object> map = (Map<String, Object>) value;
             out.writeVInt(map.size());
             for (Map.Entry<String, Object> entry : map.entrySet()) {