summaryrefslogtreecommitdiffstats
path: root/java/com/google/gerrit/index/IndexConfig.java
blob: c21f32eb5c8983d211184c1dfd79ff6d30830dfe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed 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 com.google.gerrit.index;

import static com.google.common.base.Preconditions.checkArgument;

import com.google.auto.value.AutoValue;
import java.util.function.Consumer;
import java.util.function.IntConsumer;
import org.eclipse.jgit.lib.Config;

/**
 * Implementation-specific configuration for secondary indexes.
 *
 * <p>Contains configuration that is tied to a specific index implementation but is otherwise
 * global, i.e. not tied to a specific {@link Index} and schema version.
 */
@AutoValue
public abstract class IndexConfig {
  private static final int DEFAULT_MAX_TERMS = 1024;
  private static final int DEFAULT_PAGE_SIZE_MULTIPLIER = 1;

  public static IndexConfig createDefault() {
    return builder().build();
  }

  public static Builder fromConfig(Config cfg) {
    Builder b = builder();
    setIfPresent(cfg, "maxLimit", b::maxLimit);
    setIfPresent(cfg, "maxPages", b::maxPages);
    setIfPresent(cfg, "maxTerms", b::maxTerms);
    setIfPresent(cfg, "pageSizeMultiplier", b::pageSizeMultiplier);
    setIfPresent(cfg, "maxPageSize", b::maxPageSize);
    setTypeOrDefault(cfg, b::type);
    setPaginationTypeOrDefault(cfg, b::paginationType);
    return b;
  }

  private static void setIfPresent(Config cfg, String name, IntConsumer setter) {
    int n = cfg.getInt("index", null, name, 0);
    if (n != 0) {
      setter.accept(n);
    }
  }

  private static void setTypeOrDefault(Config cfg, Consumer<String> setter) {
    String type = cfg != null ? cfg.getString("index", null, "type") : null;
    setter.accept(new IndexType(type).toString());
  }

  private static void setPaginationTypeOrDefault(Config cfg, Consumer<PaginationType> setter) {
    setter.accept(
        cfg != null ? cfg.getEnum("index", null, "paginationType", PaginationType.OFFSET) : null);
  }

  public static Builder builder() {
    return new AutoValue_IndexConfig.Builder()
        .maxLimit(Integer.MAX_VALUE)
        .maxPages(Integer.MAX_VALUE)
        .maxTerms(DEFAULT_MAX_TERMS)
        .pageSizeMultiplier(DEFAULT_PAGE_SIZE_MULTIPLIER)
        .maxPageSize(Integer.MAX_VALUE)
        .type(IndexType.getDefault())
        .separateChangeSubIndexes(false)
        .paginationType(PaginationType.OFFSET);
  }

  @AutoValue.Builder
  public abstract static class Builder {
    public abstract Builder maxLimit(int maxLimit);

    public abstract int maxLimit();

    public abstract Builder maxPages(int maxPages);

    public abstract int maxPages();

    public abstract Builder maxTerms(int maxTerms);

    public abstract int maxTerms();

    public abstract Builder type(String type);

    public abstract String type();

    public abstract Builder separateChangeSubIndexes(boolean separate);

    public abstract Builder paginationType(PaginationType type);

    public abstract Builder pageSizeMultiplier(int pageSizeMultiplier);

    public abstract Builder maxPageSize(int maxPageSize);

    abstract IndexConfig autoBuild();

    public IndexConfig build() {
      IndexConfig cfg = autoBuild();
      checkLimit(cfg.maxLimit(), "maxLimit");
      checkLimit(cfg.maxPages(), "maxPages");
      checkLimit(cfg.maxTerms(), "maxTerms");
      checkLimit(cfg.pageSizeMultiplier(), "pageSizeMultiplier");
      checkLimit(cfg.maxPageSize(), "maxPageSize");
      return cfg;
    }
  }

  private static void checkLimit(int limit, String name) {
    checkArgument(limit > 0, "%s must be positive: %s", name, limit);
  }

  /**
   * Returns maximum limit supported by the underlying index, or limited for performance reasons.
   */
  public abstract int maxLimit();

  /**
   * Returns maximum number of pages (limit / start) supported by the underlying index, or limited
   * for performance reasons.
   */
  public abstract int maxPages();

  /**
   * Returns maximum number of total index query terms supported by the underlying index, or limited
   * for performance reasons.
   */
  public abstract int maxTerms();

  /** Returns index type. */
  public abstract String type();

  /**
   * Returns whether different subsets of changes may be stored in different physical sub-indexes.
   */
  public abstract boolean separateChangeSubIndexes();

  /**
   * Returns pagination type to use when index queries are repeated to obtain the next set of
   * results.
   */
  public abstract PaginationType paginationType();

  /**
   * Returns multiplier to be used to determine the limit when queries are repeated to obtain the
   * next set of results.
   */
  public abstract int pageSizeMultiplier();

  /**
   * Returns maximum allowed limit when repeating index queries to obtain the next set of results.
   */
  public abstract int maxPageSize();
}