All Downloads are FREE. Search and download functionalities are using the official Maven repository.

shz.core.model.PageInfo Maven / Gradle / Ivy

There is a newer version: 2024.0.2
Show newest version
package shz.core.model;

import shz.core.*;
import shz.core.function.ActionRunner;
import shz.core.msg.ClientFailureMsg;
import shz.core.queue.p.*;
import shz.core.reference.ZReference;

import java.util.*;
import java.util.function.*;

public class PageInfo {
    private int page = 1;
    private int size = 10;
    private int total;
    private int pages;
    private int min;
    private int max;

    private List data = Collections.emptyList();

    private int current;
    private T currentFirst;
    private T currentLast;

    public PageInfo(int page, int size, int current, T currentFirst, T currentLast) {
        this.page = page;
        this.size = size;
        this.current = current;
        this.currentFirst = currentFirst;
        this.currentLast = currentLast;
    }

    public PageInfo() {
    }

    public static  PageInfo of(int page, int size) {
        return new PageInfo<>(page, size, 0, null, null);
    }

    public static  PageInfo max() {
        return of(1, Integer.MAX_VALUE);
    }

    public final void reset() {
        page = Math.max(1, page);
        size = Math.max(1, size);
        total = Math.max(0, total);
        pages = total % size == 0 ? total / size : total / size + 1;
        min = (page - 1) * size;
        max = total > 0 ? Math.min(min + size, total) : min + size;
    }

    public final boolean isEmpty() {
        return NullHelp.isEmpty(data);
    }

    public final boolean hasNext() {
        return max < total;
    }

    public final  PageInfo simple() {
        PageInfo pageInfo = of(page, size);
        pageInfo.total = total;
        pageInfo.pages = pages;
        pageInfo.min = min;
        pageInfo.max = max;
        pageInfo.current = current;
        return pageInfo;
    }

    public final  PageInfo map(Function mapper) {
        PageInfo pageInfo = simple();
        if (NullHelp.nonEmpty(data)) pageInfo.data = ToList.explicitCollect(data.stream().map(mapper), data.size());
        if (currentFirst != null) pageInfo.currentFirst = mapper.apply(currentFirst);
        if (currentLast != null) pageInfo.currentLast = mapper.apply(currentLast);
        return pageInfo;
    }

    @SuppressWarnings("unchecked")
    public final  PageInfo map() {
        return map(t -> (R) t);
    }

    public final int getPage() {
        return page;
    }

    public final void setPage(int page) {
        this.page = page;
    }

    public final int getSize() {
        return size;
    }

    public final void setSize(int size) {
        this.size = size;
    }

    public final int getTotal() {
        return total;
    }

    public final void setTotal(int total) {
        this.total = total;
    }

    public final int getPages() {
        return pages;
    }

    public final void setPages(int pages) {
        this.pages = pages;
    }

    public final int getMin() {
        return min;
    }

    public final void setMin(int min) {
        this.min = min;
    }

    public final int getMax() {
        return max;
    }

    public final void setMax(int max) {
        this.max = max;
    }

    public final List getData() {
        return data;
    }

    public final void setData(List data) {
        this.data = data;
    }

    public final int getCurrent() {
        return current;
    }

    public final void setCurrent(int current) {
        this.current = current;
    }

    public final T getCurrentFirst() {
        return currentFirst;
    }

    public final void setCurrentFirst(T currentFirst) {
        this.currentFirst = currentFirst;
    }

    public final T getCurrentLast() {
        return currentLast;
    }

    public final void setCurrentLast(T currentLast) {
        this.currentLast = currentLast;
    }

    @Override
    public String toString() {
        return "PageInfo{" +
                "page=" + page +
                ", size=" + size +
                ", total=" + total +
                ", pages=" + pages +
                ", min=" + min +
                ", max=" + max +
                ", data=" + data +
                ", current=" + current +
                ", currentFirst=" + currentFirst +
                ", currentLast=" + currentLast +
                '}';
    }

    public final void page(ActionRunner runner, Predicate filter, ToIntFunction> count, BiPredicate equals, Comparator comparator, boolean concurrent) {
        ClientFailureMsg.requireNon(page < 1, "页码不能小于1");
        ClientFailureMsg.requireNon(size < 1, "每页大小不能小于1");

        int offset = page - current;
        if (offset == 0) return;

        if (page == 1) {
            //首页
            List ts = ToList.topN(runner, size, filter, comparator, concurrent);
            int realSize = ts.size();
            if (realSize > 0) {
                total = realSize < size ? realSize : count.applyAsInt(filter);
                reset();
                data = ts;
                current = page;
                currentLast = data.get(realSize - 1);
            } else data = Collections.emptyList();
            return;
        }

        ClientFailureMsg.requireNon(current < 1, "当前页不能小于1");

        T currentT;
        if (offset > 0) {
            currentT = currentLast;
            ClientFailureMsg.requireNonNull(currentT, "缺少currentLast");
        } else {
            currentT = currentFirst;
            ClientFailureMsg.requireNonNull(currentT, "缺少currentFirst");
        }

        total = count.applyAsInt(filter);
        reset();
        if (total == 0 || page > pages) {
            data = Collections.emptyList();
            return;
        }

        //尾页
        if (page == pages) {
            RBBSTPQueue queue = MaxPQueue.of(comparator);
            int n = total + size - page * size;
            if (concurrent) {
                runner.accept(t -> {
                    if (t == null || (filter != null && !filter.test(t))) return;
                    synchronized (queue) {
                        while (queue.size() > n) queue.poll();
                        if (queue.size() == n) {
                            if (comparator.compare(t, queue.peek()) >= 0) {
                                queue.poll();
                                queue.offer(t);
                            }
                        } else queue.offer(t);
                    }
                });
            } else runner.accept(t -> {
                if (t == null || (filter != null && !filter.test(t))) return;
                while (queue.size() > n) queue.poll();
                if (queue.size() == n) {
                    if (comparator.compare(t, queue.peek()) >= 0) {
                        queue.poll();
                        queue.offer(t);
                    }
                } else queue.offer(t);
            });
            int realSize = queue.size();
            if (realSize > 0) {
                data = queue.toList();
                current = page;
                currentFirst = data.get(0);
            } else data = Collections.emptyList();
            return;
        }

        //根据向前翻页或向后翻页选择不同的优先队列,保证顺序始终一致
        RBBSTPQueue queue = offset > 0 ? MinPQueue.of(comparator) : MaxPQueue.of(comparator);
        ZReference mark = new ZReference();
        int n = Math.abs(offset) * size;
        if (concurrent) {
            runner.accept(t -> {
                if (t == null || (filter != null && !filter.test(t))) return;
                int cmp = comparator.compare(t, currentT);
                if (cmp < 0 && offset > 0 || cmp > 0 && offset < 0) return;
                synchronized (queue) {
                    if (cmp == 0) {
                        if (mark.get()) {
                            if (offset < 0) return;
                        } else {
                            mark.set(equals.test(currentT, t));
                            if (mark.get() || offset > 0) return;
                        }
                    }
                    while (queue.size() > n) queue.poll();
                    if (queue.size() == n) {
                        cmp = comparator.compare(t, queue.peek());
                        if ((cmp < 0 && offset > 0) || (cmp >= 0 && offset < 0)) {
                            queue.poll();
                            queue.offer(t);
                        }
                    } else queue.offer(t);
                }
            });
        } else runner.accept(t -> {
            if (t == null || (filter != null && !filter.test(t))) return;
            int cmp = comparator.compare(t, currentT);
            if (cmp < 0) {
                if (offset > 0) return;
            } else if (cmp > 0) {
                if (offset < 0) return;
            } else {
                if (mark.get()) {
                    if (offset < 0) return;
                } else {
                    mark.set(equals.test(currentT, t));
                    if (mark.get() || offset > 0) return;
                }
            }
            while (queue.size() > n) queue.poll();
            if (queue.size() == n) {
                cmp = comparator.compare(t, queue.peek());
                if ((cmp < 0 && offset > 0) || (cmp >= 0 && offset < 0)) {
                    queue.poll();
                    queue.offer(t);
                }
            } else queue.offer(t);
        });
        int realSize = queue.size() + size - n;
        if (realSize > 0) {
            if (offset > 0) data = queue.reverse(realSize);
            else data = queue.toList(realSize);
            current = page;
            currentFirst = data.get(0);
            currentLast = data.get(realSize - 1);
        } else data = Collections.emptyList();
    }

    public final void page(ActionRunner runner, Predicate filter, ToIntFunction> count, BiPredicate equals, Comparator comparator) {
        page(runner, filter, count, equals, comparator, false);
    }

    public final void page(Supplier supplier, Predicate filter, ToIntFunction> count, BiPredicate equals, Comparator comparator) {
        page(Runner.runner(supplier), filter, count, equals, comparator, false);
    }

    public final void page(Collection dataset, Predicate filter, BiPredicate equals, Comparator comparator) {
        page(
                Runner.runner(dataset), filter,
                predicate -> filter == null ? dataset.size() : Math.toIntExact(dataset.stream().filter(filter).count()),
                equals, comparator, false
        );
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy