1 /*
2 * Copyright (C) 2017, Google Inc.
3 * and other copyright owners as documented in the project's IP log.
4 *
5 * This program and the accompanying materials are made available
6 * under the terms of the Eclipse Distribution License v1.0 which
7 * accompanies this distribution, is reproduced below, and is
8 * available at http://www.eclipse.org/org/documents/edl-v10.php
9 *
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * - Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 *
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials provided
22 * with the distribution.
23 *
24 * - Neither the name of the Eclipse Foundation, Inc. nor the
25 * names of its contributors may be used to endorse or promote
26 * products derived from this software without specific prior
27 * written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 */
43
44 package org.eclipse.jgit.internal.storage.reftable;
45
46 import static org.eclipse.jgit.internal.storage.reftable.ReftableConstants.MAX_BLOCK_SIZE;
47
48 import org.eclipse.jgit.lib.Config;
49 import org.eclipse.jgit.lib.Repository;
50
51 /** Configuration used by a reftable writer when constructing the stream. */
52 public class ReftableConfig {
53 private int refBlockSize = 4 << 10;
54 private int logBlockSize;
55 private int restartInterval;
56 private int maxIndexLevels;
57 private boolean alignBlocks = true;
58 private boolean indexObjects = true;
59
60 /** Create a default configuration. */
61 public ReftableConfig() {
62 }
63
64 /**
65 * Create a configuration honoring the repository's settings.
66 *
67 * @param db
68 * the repository to read settings from. The repository is not
69 * retained by the new configuration, instead its settings are
70 * copied during the constructor.
71 */
72 public ReftableConfig(Repository db) {
73 fromConfig(db.getConfig());
74 }
75
76 /**
77 * Create a configuration honoring settings in a {@link Config}.
78 *
79 * @param cfg
80 * the source to read settings from. The source is not retained
81 * by the new configuration, instead its settings are copied
82 * during the constructor.
83 */
84 public ReftableConfig(Config cfg) {
85 fromConfig(cfg);
86 }
87
88 /**
89 * Copy an existing configuration to a new instance.
90 *
91 * @param cfg
92 * the source configuration to copy from.
93 */
94 public ReftableConfig(ReftableConfig cfg) {
95 this.refBlockSize = cfg.refBlockSize;
96 this.logBlockSize = cfg.logBlockSize;
97 this.restartInterval = cfg.restartInterval;
98 this.maxIndexLevels = cfg.maxIndexLevels;
99 this.alignBlocks = cfg.alignBlocks;
100 this.indexObjects = cfg.indexObjects;
101 }
102
103 /** @return desired output block size for references, in bytes */
104 public int getRefBlockSize() {
105 return refBlockSize;
106 }
107
108 /**
109 * @param szBytes
110 * desired output block size for references, in bytes.
111 */
112 public void setRefBlockSize(int szBytes) {
113 if (szBytes > MAX_BLOCK_SIZE) {
114 throw new IllegalArgumentException();
115 }
116 refBlockSize = Math.max(0, szBytes);
117 }
118
119 /**
120 * @return desired output block size for log entries, in bytes. If 0 the
121 * writer will default to {@code 2 * getRefBlockSize()}.
122 */
123 public int getLogBlockSize() {
124 return logBlockSize;
125 }
126
127 /**
128 * @param szBytes
129 * desired output block size for log entries, in bytes. If 0 will
130 * default to {@code 2 * getRefBlockSize()}.
131 */
132 public void setLogBlockSize(int szBytes) {
133 if (szBytes > MAX_BLOCK_SIZE) {
134 throw new IllegalArgumentException();
135 }
136 logBlockSize = Math.max(0, szBytes);
137 }
138
139 /** @return number of references between binary search markers. */
140 public int getRestartInterval() {
141 return restartInterval;
142 }
143
144 /**
145 * @param interval
146 * number of references between binary search markers. If
147 * {@code interval} is 0 (default), the writer will select a
148 * default value based on the block size.
149 */
150 public void setRestartInterval(int interval) {
151 restartInterval = Math.max(0, interval);
152 }
153
154 /** @return maximum depth of the index; 0 for unlimited. */
155 public int getMaxIndexLevels() {
156 return maxIndexLevels;
157 }
158
159 /**
160 * @param levels
161 * maximum number of levels to use in indexes. Lower levels of
162 * the index respect {@link #getRefBlockSize()}, and the highest
163 * level may exceed that if the number of levels is limited.
164 */
165 public void setMaxIndexLevels(int levels) {
166 maxIndexLevels = Math.max(0, levels);
167 }
168
169 /** @return {@code true} if the writer should align blocks. */
170 public boolean isAlignBlocks() {
171 return alignBlocks;
172 }
173
174 /**
175 * @param align
176 * if {@code true} blocks are written aligned to multiples of
177 * {@link #getRefBlockSize()}. May increase file size due to NUL
178 * padding bytes added between blocks. Default is {@code true}.
179 */
180 public void setAlignBlocks(boolean align) {
181 alignBlocks = align;
182 }
183
184 /** @return {@code true} if the writer should index object to ref. */
185 public boolean isIndexObjects() {
186 return indexObjects;
187 }
188
189 /**
190 * @param index
191 * if {@code true} the reftable may include additional storage to
192 * efficiently map from {@code ObjectId} to reference names. By
193 * default, {@code true}.
194 */
195 public void setIndexObjects(boolean index) {
196 indexObjects = index;
197 }
198
199 /**
200 * Update properties by setting fields from the configuration.
201 *
202 * If a property's corresponding variable is not defined in the supplied
203 * configuration, then it is left unmodified.
204 *
205 * @param rc
206 * configuration to read properties from.
207 */
208 public void fromConfig(Config rc) {
209 refBlockSize = rc.getInt("reftable", "blockSize", refBlockSize); //$NON-NLS-1$ //$NON-NLS-2$
210 logBlockSize = rc.getInt("reftable", "logBlockSize", logBlockSize); //$NON-NLS-1$ //$NON-NLS-2$
211 restartInterval = rc.getInt("reftable", "restartInterval", restartInterval); //$NON-NLS-1$ //$NON-NLS-2$
212 maxIndexLevels = rc.getInt("reftable", "indexLevels", maxIndexLevels); //$NON-NLS-1$ //$NON-NLS-2$
213 alignBlocks = rc.getBoolean("reftable", "alignBlocks", alignBlocks); //$NON-NLS-1$ //$NON-NLS-2$
214 indexObjects = rc.getBoolean("reftable", "indexObjects", indexObjects); //$NON-NLS-1$ //$NON-NLS-2$
215 }
216 }