Skip to content

Commit 592edca

Browse files
hanwengitster
authored andcommitted
Add reftable library
Reftable is a new format for storing the ref database. It provides the following benefits: * Simple and fast atomic ref transactions, including multiple refs and reflogs. * Compact storage of ref data. * Fast look ups of ref data. * Case-sensitive ref names on Windows/OSX, regardless of file system * Eliminates file/directory conflicts in ref names Further context and motivation can be found in background reading: * Spec: https://github.com/eclipse/jgit/blob/master/Documentation/technical/reftable.md * Original discussion on JGit-dev: https://www.eclipse.org/lists/jgit-dev/msg03389.html * First design discussion on git@vger: https://public-inbox.org/git/CAJo=hJtTp2eA3z9wW9cHo-nA7kK40vVThqh6inXpbCcqfdMP9g@mail.gmail.com/ * Last design discussion on git@vger: https://public-inbox.org/git/CAJo=hJsZcAM9sipdVr7TMD-FD2V2W6_pvMQ791EGCDsDkQ033w@mail.gmail.com/ * First attempt at implementation: https://public-inbox.org/git/CAP8UFD0PPZSjBnxCA7ez91vBuatcHKQ+JUWvTD1iHcXzPBjPBg@mail.gmail.com/ * libgit2 support issue: https://github.com/libgit2/libgit2/issues * GitLab support issue: https://gitlab.com/gitlab-org/git/issues/6 * go-git support issue: src-d/go-git#1059 Signed-off-by: Han-Wen Nienhuys <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c2f9b15 commit 592edca

34 files changed

+6267
-0
lines changed

reftable/LICENSE

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
BSD License
2+
3+
Copyright (c) 2020, Google LLC
4+
All rights reserved.
5+
6+
Redistribution and use in source and binary forms, with or without
7+
modification, are permitted provided that the following conditions are
8+
met:
9+
10+
* Redistributions of source code must retain the above copyright notice,
11+
this list of conditions and the following disclaimer.
12+
13+
* Redistributions in binary form must reproduce the above copyright
14+
notice, this list of conditions and the following disclaimer in the
15+
documentation and/or other materials provided with the distribution.
16+
17+
* Neither the name of Google LLC nor the names of its contributors may
18+
be used to endorse or promote products derived from this software
19+
without specific prior written permission.
20+
21+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

reftable/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
The source code in this directory comes from https://github.com/google/reftable.
3+
4+
The VERSION file keeps track of the current version of the reftable library.
5+
6+
To update the library, do:
7+
8+
((cd reftable-repo && git fetch origin && git checkout origin/master ) ||
9+
git clone https://github.com/google/reftable reftable-repo) && \
10+
cp reftable-repo/c/*.[ch] reftable/ && \
11+
cp reftable-repo/LICENSE reftable/ &&
12+
git --git-dir reftable-repo/.git show --no-patch origin/master \
13+
> reftable/VERSION && \
14+
echo '/* empty */' > reftable/config.h
15+
rm reftable/*_test.c reftable/test_framework.*
16+
git add reftable/*.[ch]
17+
18+
Bugfixes should be accompanied by a test and applied to upstream project at
19+
https://github.com/google/reftable.

reftable/VERSION

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
commit e7c3fc3099d9999bc8d895f84027b0e36348d5e6
2+
Author: Han-Wen Nienhuys <[email protected]>
3+
Date: Thu Feb 6 20:17:40 2020 +0100
4+
5+
C: use inttypes.h header definitions

reftable/basics.c

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
/*
2+
Copyright 2020 Google LLC
3+
4+
Use of this source code is governed by a BSD-style
5+
license that can be found in the LICENSE file or at
6+
https://developers.google.com/open-source/licenses/bsd
7+
*/
8+
9+
#include "basics.h"
10+
11+
#include "system.h"
12+
13+
void put_u24(byte *out, uint32_t i)
14+
{
15+
out[0] = (byte)((i >> 16) & 0xff);
16+
out[1] = (byte)((i >> 8) & 0xff);
17+
out[2] = (byte)((i)&0xff);
18+
}
19+
20+
uint32_t get_u24(byte *in)
21+
{
22+
return (uint32_t)(in[0]) << 16 | (uint32_t)(in[1]) << 8 |
23+
(uint32_t)(in[2]);
24+
}
25+
26+
void put_u32(byte *out, uint32_t i)
27+
{
28+
out[0] = (byte)((i >> 24) & 0xff);
29+
out[1] = (byte)((i >> 16) & 0xff);
30+
out[2] = (byte)((i >> 8) & 0xff);
31+
out[3] = (byte)((i)&0xff);
32+
}
33+
34+
uint32_t get_u32(byte *in)
35+
{
36+
return (uint32_t)(in[0]) << 24 | (uint32_t)(in[1]) << 16 |
37+
(uint32_t)(in[2]) << 8 | (uint32_t)(in[3]);
38+
}
39+
40+
void put_u64(byte *out, uint64_t v)
41+
{
42+
int i = 0;
43+
for (i = sizeof(uint64_t); i--;) {
44+
out[i] = (byte)(v & 0xff);
45+
v >>= 8;
46+
}
47+
}
48+
49+
uint64_t get_u64(byte *out)
50+
{
51+
uint64_t v = 0;
52+
int i = 0;
53+
for (i = 0; i < sizeof(uint64_t); i++) {
54+
v = (v << 8) | (byte)(out[i] & 0xff);
55+
}
56+
return v;
57+
}
58+
59+
void put_u16(byte *out, uint16_t i)
60+
{
61+
out[0] = (byte)((i >> 8) & 0xff);
62+
out[1] = (byte)((i)&0xff);
63+
}
64+
65+
uint16_t get_u16(byte *in)
66+
{
67+
return (uint32_t)(in[0]) << 8 | (uint32_t)(in[1]);
68+
}
69+
70+
/*
71+
find smallest index i in [0, sz) at which f(i) is true, assuming
72+
that f is ascending. Return sz if f(i) is false for all indices.
73+
*/
74+
int binsearch(int sz, int (*f)(int k, void *args), void *args)
75+
{
76+
int lo = 0;
77+
int hi = sz;
78+
79+
/* invariant: (hi == sz) || f(hi) == true
80+
(lo == 0 && f(0) == true) || fi(lo) == false
81+
*/
82+
while (hi - lo > 1) {
83+
int mid = lo + (hi - lo) / 2;
84+
85+
int val = f(mid, args);
86+
if (val) {
87+
hi = mid;
88+
} else {
89+
lo = mid;
90+
}
91+
}
92+
93+
if (lo == 0) {
94+
if (f(0, args)) {
95+
return 0;
96+
} else {
97+
return 1;
98+
}
99+
}
100+
101+
return hi;
102+
}
103+
104+
void free_names(char **a)
105+
{
106+
char **p = a;
107+
if (p == NULL) {
108+
return;
109+
}
110+
while (*p) {
111+
free(*p);
112+
p++;
113+
}
114+
free(a);
115+
}
116+
117+
int names_length(char **names)
118+
{
119+
int len = 0;
120+
for (char **p = names; *p; p++) {
121+
len++;
122+
}
123+
return len;
124+
}
125+
126+
/* parse a newline separated list of names. Empty names are discarded. */
127+
void parse_names(char *buf, int size, char ***namesp)
128+
{
129+
char **names = NULL;
130+
int names_cap = 0;
131+
int names_len = 0;
132+
133+
char *p = buf;
134+
char *end = buf + size;
135+
while (p < end) {
136+
char *next = strchr(p, '\n');
137+
if (next != NULL) {
138+
*next = 0;
139+
} else {
140+
next = end;
141+
}
142+
if (p < next) {
143+
if (names_len == names_cap) {
144+
names_cap = 2 * names_cap + 1;
145+
names = realloc(names,
146+
names_cap * sizeof(char *));
147+
}
148+
names[names_len++] = strdup(p);
149+
}
150+
p = next + 1;
151+
}
152+
153+
if (names_len == names_cap) {
154+
names_cap = 2 * names_cap + 1;
155+
names = realloc(names, names_cap * sizeof(char *));
156+
}
157+
158+
names[names_len] = NULL;
159+
*namesp = names;
160+
}
161+
162+
int names_equal(char **a, char **b)
163+
{
164+
while (*a && *b) {
165+
if (strcmp(*a, *b)) {
166+
return 0;
167+
}
168+
169+
a++;
170+
b++;
171+
}
172+
173+
return *a == *b;
174+
}
175+
176+
const char *error_str(int err)
177+
{
178+
switch (err) {
179+
case IO_ERROR:
180+
return "I/O error";
181+
case FORMAT_ERROR:
182+
return "FORMAT_ERROR";
183+
case NOT_EXIST_ERROR:
184+
return "NOT_EXIST_ERROR";
185+
case LOCK_ERROR:
186+
return "LOCK_ERROR";
187+
case API_ERROR:
188+
return "API_ERROR";
189+
case ZLIB_ERROR:
190+
return "ZLIB_ERROR";
191+
case -1:
192+
return "general error";
193+
default:
194+
return "unknown error code";
195+
}
196+
}

reftable/basics.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
Copyright 2020 Google LLC
3+
4+
Use of this source code is governed by a BSD-style
5+
license that can be found in the LICENSE file or at
6+
https://developers.google.com/open-source/licenses/bsd
7+
*/
8+
9+
#ifndef BASICS_H
10+
#define BASICS_H
11+
12+
#include "system.h"
13+
14+
#include "reftable.h"
15+
16+
#define true 1
17+
#define false 0
18+
19+
void put_u24(byte *out, uint32_t i);
20+
uint32_t get_u24(byte *in);
21+
22+
uint64_t get_u64(byte *in);
23+
void put_u64(byte *out, uint64_t i);
24+
25+
void put_u32(byte *out, uint32_t i);
26+
uint32_t get_u32(byte *in);
27+
28+
void put_u16(byte *out, uint16_t i);
29+
uint16_t get_u16(byte *in);
30+
int binsearch(int sz, int (*f)(int k, void *args), void *args);
31+
32+
void free_names(char **a);
33+
void parse_names(char *buf, int size, char ***namesp);
34+
int names_equal(char **a, char **b);
35+
int names_length(char **names);
36+
37+
#endif

0 commit comments

Comments
 (0)