Add a cache around getpwuid/getgrgid to avoid repeated calls.
[cumulus.git] / ref.h
1 /* Cumulus: Smart Filesystem Backup to Dumb Servers
2  *
3  * Copyright (C) 2007-2008  The Regents of the University of California
4  * Written by Michael Vrable <mvrable@cs.ucsd.edu>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20
21 /* Backups are structured as a collection of objects, which may refer to other
22  * objects.  Object references are used to name other objects or parts of them.
23  * This file defines the class for representing object references and the
24  * textual representation of these references. */
25
26 #ifndef _LBS_REF_H
27 #define _LBS_REF_H
28
29 #include <string>
30
31 /* ======================== Object Reference Syntax ========================
32  *
33  * Segments are groups of objects.  Segments are named by UUID, which is a
34  * 128-bit value.  The text representation is
35  *    <segment> ::= xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxx
36  * where each <x> is a lowercase hexadecimal digit ([0-9a-f]).
37  *
38  * Each object within a segment is assigned a sequence number, which is given
39  * as a hexadecimal value:
40  *    <object-seq> ::= xxxxxxxx
41  *
42  * An object can be uniquely named by the combination of segment name and
43  * object sequence number:
44  *    <object-name> ::= <segment> "/" <object-seq>
45  * Example: "cf47429e-a503-43ac-9c31-bb3175fbb820/0000002b"
46  *
47  * An object name may optionally be suffixed with a checksum, which allows
48  * checking the integrity of the referenced object.
49  *    <checksum> ::= <checksum-alg> "=" <checksum-value>
50  * Currently the only checksum-alg is "sha1", but others may be defined later.
51  * <checksum-value> is a hexadecimal string.  If included, the checksum is
52  * enclosed in parentheses.
53  *
54  * Each object is stored as a string of bytes, and object reference may specify
55  * a substring rather than the entire string using a range specifier.  If no
56  * range specifier is given, then by default the entire object is used.
57  *    <range> ::= <start> "+" <length>
58  *                | <length>
59  *                | "=" <length>
60  * Both <start> and <length> are decimal values.  If included, the range is
61  * enclosed in brackets.  As an abbreviation, if <start> is 0 then the range
62  * can be given as just <length> (no "+" needed).  The "=<length>" form asserts
63  * that the underlying object is exactly <length> bytes in size.
64  *
65  * When both a checksum and a range are included, note that the checksum is
66  * taken over the entire original object, before the range is taken into
67  * account.
68  *
69  * The full syntax for an object reference is:
70  *    <object-reference>
71  *      ::= <object-name> [ "(" <checksum> ")" ] [ "[" <range> "]" ]
72  * Example: "cf47429e-a503-43ac-9c31-bb3175fbb820/0000002b(sha1=b9f5d0a21b8d07356723f041f5463dec892654af)[1024+512]"
73  *
74  * Finally, in specific circumstances, and indirect reference may be used.  In
75  * cases where data could be listed directly, instead an object reference can
76  * be given, prefixed with "@", which indicates that the data stored at the
77  * referenced object should be treated as being included.
78  *    <indirect-reference> ::= "@" <object-reference>
79  */
80
81 /* Generate a fresh UUID, suitable for use as a segment name. */
82 std::string generate_uuid();
83
84 /* Class representing an object reference, which allows it to be manipulated
85  * and converted to and from the text representation. */
86 class ObjectReference {
87 public:
88     enum RefType { REF_NULL, REF_ZERO, REF_NORMAL };
89
90     ObjectReference();
91     ObjectReference(RefType t);
92     ObjectReference(const std::string& segment, int sequence);
93     ObjectReference(const std::string& segment, const std::string& sequence);
94
95     bool is_null() const { return type == REF_NULL; }
96     bool is_normal() const { return type == REF_NORMAL; }
97     std::string to_string() const;
98     static ObjectReference parse(const std::string& s);
99
100     std::string get_segment() const { return segment; }
101     std::string get_sequence() const { return object; }
102     std::string get_basename() const { return segment + "/" + object; }
103     ObjectReference base() const { return ObjectReference(segment, object); }
104
105     bool has_checksum() const { return checksum_valid; }
106     std::string get_checksum() const { return checksum; }
107     void clear_checksum() { checksum = ""; checksum_valid = false; }
108     void set_checksum(const std::string& checksum)
109         { this->checksum = checksum; checksum_valid = true; }
110
111     bool has_range() const { return range_valid; }
112     size_t get_range_start() const { return range_start; }
113     size_t get_range_length() const { return range_length; }
114     size_t get_range_exact() const { return range_exact; }
115     void clear_range()
116         { range_start = range_length = 0;
117           range_valid = false; range_exact = false; }
118     void set_range(size_t start, size_t length, bool exact = false)
119         { range_start = start; range_length = length;
120           range_valid = true; range_exact = exact; }
121
122     bool merge(ObjectReference ref);
123
124     // Maybe provide non-string implementations?
125     bool operator==(const ObjectReference &x) const
126         { return to_string() == x.to_string(); }
127     bool operator<(const ObjectReference &x) const
128         { return to_string() < x.to_string(); }
129
130 private:
131     RefType type;
132     std::string segment, object, checksum;
133     size_t range_start, range_length;
134     bool checksum_valid, range_valid, range_exact;
135 };
136
137 #endif // _LBS_REF_H