社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Elasticsearch

聊聊Elasticsearch的Iterables

go4it • 6 年前 • 341 次点击  
阅读 4

聊聊Elasticsearch的Iterables

本文主要研究一下Elasticsearch的Iterables

Iterables

elasticsearch-7.0.1/server/src/main/java/org/elasticsearch/common/util/iterable/Iterables.java

public class Iterables {

    public static <T> Iterable<T> concat(Iterable<T>... inputs) {
        Objects.requireNonNull(inputs);
        return new ConcatenatedIterable<>(inputs);
    }

    static class ConcatenatedIterable<T> implements Iterable<T> {
        private final Iterable<T>[] inputs;

        ConcatenatedIterable(Iterable<T>[] inputs) {
            this.inputs = Arrays.copyOf(inputs, inputs.length);
        }

        @Override
        public Iterator<T> iterator() {
            return Stream
                    .of(inputs)
                    .map(it -> StreamSupport.stream(it.spliterator(), false))
                    .reduce(Stream::concat)
                    .orElseGet(Stream::empty).iterator();
        }
    }

    /** Flattens the two level {@code Iterable} into a single {@code Iterable}.  Note that this pre-caches the values from the outer {@code
     *  Iterable}, but not the values from the inner one. */
    public static <T> Iterable<T> flatten(Iterable<? extends Iterable<T>> inputs) {
        Objects.requireNonNull(inputs);
        return new FlattenedIterables<>(inputs);
    }

    static class FlattenedIterables<T> implements Iterable<T> {
        private final Iterable<? extends Iterable<T>> inputs;

        FlattenedIterables(Iterable<? extends Iterable<T>> inputs) {
            List<Iterable<T>> list = new ArrayList<>();
            for (Iterable<T> iterable : inputs) {
                list.add(iterable);
            }
            this.inputs = list;
        }

        @Override
        public Iterator<T> iterator() {
            return StreamSupport
                    .stream(inputs.spliterator(), false)
                    .flatMap(s -> StreamSupport.stream(s.spliterator(), false)).iterator();
        }
    }

    public static <T> T get(Iterable<T> iterable, int position) {
        Objects.requireNonNull(iterable);
        if (position < 0) {
            throw new IllegalArgumentException("position >= 0");
        }
        if (iterable instanceof List) {
            List<T> list = (List<T>)iterable;
            if (position >= list.size()) {
                throw new IndexOutOfBoundsException(Integer.toString(position));
            }
            return list.get(position);
        } else {
            Iterator<T> it = iterable.iterator();
            for (int index = 0; index < position; index++) {
                if (!it.hasNext()) {
                    throw new IndexOutOfBoundsException(Integer.toString(position));
                }
                it.next();
            }
            if (!it.hasNext()) {
                throw new IndexOutOfBoundsException(Integer.toString(position));
            }
            return it.next();
        }
    }
}
复制代码
  • Iterables提供了concat、flatten、get三个静态方法,其中concat返回的是ConcatenatedIterable;flatten返回的是FlattenedIterables;get方法会先判断是否是List类型是的话直接通过position取值返回,不是则遍历iterable获取指定index的元素

实例

elasticsearch-7.0.1/server/src/test/java/org/elasticsearch/common/util/iterable/IterablesTests.java

public class IterablesTests extends ESTestCase {
    public void testGetOverList() {
        test(Arrays.asList("a", "b", "c"));
    }

    public void testGetOverIterable() {
        Iterable<String> iterable = () ->
                new Iterator<String>() {
                    private int position = 0;

                    @Override
                    public boolean hasNext() {
                        return position < 3;
                    }

                    @Override
                    public String next() {
                        if (position < 3) {
                            String s = position == 0 ? "a" : position == 1 ? "b" : "c";
                            position++;
                            return s;
                        } else {
                            throw new NoSuchElementException();
                        }
                    }
                };
        test(iterable);
    }

    public void testFlatten() {
        List<List<Integer>> list = new ArrayList<>();
        list.add(new ArrayList<>());

        Iterable<Integer> allInts = Iterables.flatten(list);
        int count = 0;
        for(@SuppressWarnings("unused") int x : allInts) {
            count++;
        }
        assertEquals(0, count);
        list.add(new ArrayList<>());
        list.get(1).add(0);

        // changes to the outer list are not seen since flatten pre-caches outer list on init:
        count = 0;
        for(@SuppressWarnings("unused") int x : allInts) {
            count++;
        }
        assertEquals(0, count);

        // but changes to the original inner lists are seen:
        list.get(0).add(0);
        for(@SuppressWarnings("unused") int x : allInts) {
            count++;
        }
        assertEquals(1, count);
    }

    private void test(Iterable<String> iterable) {
        try {
            Iterables.get(iterable, -1);
            fail("expected IllegalArgumentException");
        } catch (IllegalArgumentException e) {
            assertThat(e, hasToString("java.lang.IllegalArgumentException: position >= 0"));
        }
        assertEquals("a", Iterables.get(iterable, 0));
        assertEquals("b", Iterables.get(iterable, 1));
        assertEquals("c", Iterables.get(iterable, 2));
        try {
            Iterables.get(iterable, 3);
            fail("expected IndexOutOfBoundsException"


    
);
        } catch (IndexOutOfBoundsException e) {
            assertThat(e, hasToString("java.lang.IndexOutOfBoundsException: 3"));
        }
    }
}
复制代码
  • flatten用于将Iterable类型的Iterable进行flat操作;get方法则获取iterable中指定index的元素

小结

Iterables提供了concat、flatten、get三个静态方法,其中concat返回的是ConcatenatedIterable;flatten返回的是FlattenedIterables;get方法会先判断是否是List类型是的话直接通过position取值返回,不是则遍历iterable获取指定index的元素

doc

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/34232
 
341 次点击