~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to contrib/NGit/NGit/ObjectReader.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
ImportĀ upstreamĀ versionĀ 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
This code is derived from jgit (http://eclipse.org/jgit).
 
3
Copyright owners are documented in jgit'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
using System.Collections.Generic;
 
45
using NGit;
 
46
using NGit.Errors;
 
47
using NGit.Revwalk;
 
48
using Sharpen;
 
49
 
 
50
namespace NGit
 
51
{
 
52
        /// <summary>
 
53
        /// Reads an
 
54
        /// <see cref="ObjectDatabase">ObjectDatabase</see>
 
55
        /// for a single thread.
 
56
        /// <p>
 
57
        /// Readers that can support efficient reuse of pack encoded objects should also
 
58
        /// implement the companion interface
 
59
        /// <see cref="NGit.Storage.Pack.ObjectReuseAsIs">NGit.Storage.Pack.ObjectReuseAsIs</see>
 
60
        /// .
 
61
        /// </summary>
 
62
        public abstract class ObjectReader
 
63
        {
 
64
                /// <summary>Type hint indicating the caller doesn't know the type.</summary>
 
65
                /// <remarks>Type hint indicating the caller doesn't know the type.</remarks>
 
66
                public const int OBJ_ANY = -1;
 
67
 
 
68
                /// <summary>Construct a new reader from the same data.</summary>
 
69
                /// <remarks>
 
70
                /// Construct a new reader from the same data.
 
71
                /// <p>
 
72
                /// Applications can use this method to build a new reader from the same data
 
73
                /// source, but for an different thread.
 
74
                /// </remarks>
 
75
                /// <returns>a brand new reader, using the same data source.</returns>
 
76
                public abstract ObjectReader NewReader();
 
77
 
 
78
                /// <summary>Obtain a unique abbreviation (prefix) of an object SHA-1.</summary>
 
79
                /// <remarks>
 
80
                /// Obtain a unique abbreviation (prefix) of an object SHA-1.
 
81
                /// This method uses a reasonable default for the minimum length. Callers who
 
82
                /// don't care about the minimum length should prefer this method.
 
83
                /// The returned abbreviation would expand back to the argument ObjectId when
 
84
                /// passed to
 
85
                /// <see cref="Resolve(AbbreviatedObjectId)">Resolve(AbbreviatedObjectId)</see>
 
86
                /// , assuming no new objects
 
87
                /// are added to this repository between calls.
 
88
                /// </remarks>
 
89
                /// <param name="objectId">object identity that needs to be abbreviated.</param>
 
90
                /// <returns>SHA-1 abbreviation.</returns>
 
91
                /// <exception cref="System.IO.IOException">the object store cannot be read.</exception>
 
92
                public virtual AbbreviatedObjectId Abbreviate(AnyObjectId objectId)
 
93
                {
 
94
                        return Abbreviate(objectId, 7);
 
95
                }
 
96
 
 
97
                /// <summary>Obtain a unique abbreviation (prefix) of an object SHA-1.</summary>
 
98
                /// <remarks>
 
99
                /// Obtain a unique abbreviation (prefix) of an object SHA-1.
 
100
                /// The returned abbreviation would expand back to the argument ObjectId when
 
101
                /// passed to
 
102
                /// <see cref="Resolve(AbbreviatedObjectId)">Resolve(AbbreviatedObjectId)</see>
 
103
                /// , assuming no new objects
 
104
                /// are added to this repository between calls.
 
105
                /// The default implementation of this method abbreviates the id to the
 
106
                /// minimum length, then resolves it to see if there are multiple results.
 
107
                /// When multiple results are found, the length is extended by 1 and resolve
 
108
                /// is tried again.
 
109
                /// </remarks>
 
110
                /// <param name="objectId">object identity that needs to be abbreviated.</param>
 
111
                /// <param name="len">
 
112
                /// minimum length of the abbreviated string. Must be in the range
 
113
                /// [2,
 
114
                /// <value>Constants#OBJECT_ID_STRING_LENGTH</value>
 
115
                /// ].
 
116
                /// </param>
 
117
                /// <returns>
 
118
                /// SHA-1 abbreviation. If no matching objects exist in the
 
119
                /// repository, the abbreviation will match the minimum length.
 
120
                /// </returns>
 
121
                /// <exception cref="System.IO.IOException">the object store cannot be read.</exception>
 
122
                public virtual AbbreviatedObjectId Abbreviate(AnyObjectId objectId, int len)
 
123
                {
 
124
                        if (len == Constants.OBJECT_ID_STRING_LENGTH)
 
125
                        {
 
126
                                return AbbreviatedObjectId.FromObjectId(objectId);
 
127
                        }
 
128
                        AbbreviatedObjectId abbrev = objectId.Abbreviate(len);
 
129
                        ICollection<ObjectId> matches = Resolve(abbrev);
 
130
                        while (1 < matches.Count && len < Constants.OBJECT_ID_STRING_LENGTH)
 
131
                        {
 
132
                                abbrev = objectId.Abbreviate(++len);
 
133
                                IList<ObjectId> n = new AList<ObjectId>(8);
 
134
                                foreach (ObjectId candidate in matches)
 
135
                                {
 
136
                                        if (abbrev.PrefixCompare(candidate) == 0)
 
137
                                        {
 
138
                                                n.AddItem(candidate);
 
139
                                        }
 
140
                                }
 
141
                                if (1 < n.Count)
 
142
                                {
 
143
                                        matches = n;
 
144
                                }
 
145
                                else
 
146
                                {
 
147
                                        matches = Resolve(abbrev);
 
148
                                }
 
149
                        }
 
150
                        return abbrev;
 
151
                }
 
152
 
 
153
                /// <summary>Resolve an abbreviated ObjectId to its full form.</summary>
 
154
                /// <remarks>
 
155
                /// Resolve an abbreviated ObjectId to its full form.
 
156
                /// This method searches for an ObjectId that begins with the abbreviation,
 
157
                /// and returns at least some matching candidates.
 
158
                /// If the returned collection is empty, no objects start with this
 
159
                /// abbreviation. The abbreviation doesn't belong to this repository, or the
 
160
                /// repository lacks the necessary objects to complete it.
 
161
                /// If the collection contains exactly one member, the abbreviation is
 
162
                /// (currently) unique within this database. There is a reasonably high
 
163
                /// probability that the returned id is what was previously abbreviated.
 
164
                /// If the collection contains 2 or more members, the abbreviation is not
 
165
                /// unique. In this case the implementation is only required to return at
 
166
                /// least 2 candidates to signal the abbreviation has conflicts. User
 
167
                /// friendly implementations should return as many candidates as reasonably
 
168
                /// possible, as the caller may be able to disambiguate further based on
 
169
                /// context. However since databases can be very large (e.g. 10 million
 
170
                /// objects) returning 625,000 candidates for the abbreviation "0" is simply
 
171
                /// unreasonable, so implementors should draw the line at around 256 matches.
 
172
                /// </remarks>
 
173
                /// <param name="id">
 
174
                /// abbreviated id to resolve to a complete identity. The
 
175
                /// abbreviation must have a length of at least 2.
 
176
                /// </param>
 
177
                /// <returns>candidates that begin with the abbreviated identity.</returns>
 
178
                /// <exception cref="System.IO.IOException">the object store cannot be read.</exception>
 
179
                public abstract ICollection<ObjectId> Resolve(AbbreviatedObjectId id);
 
180
 
 
181
                /// <summary>Does the requested object exist in this database?</summary>
 
182
                /// <param name="objectId">identity of the object to test for existence of.</param>
 
183
                /// <returns>true if the specified object is stored in this database.</returns>
 
184
                /// <exception cref="System.IO.IOException">the object store cannot be accessed.</exception>
 
185
                public virtual bool Has(AnyObjectId objectId)
 
186
                {
 
187
                        return Has(objectId, OBJ_ANY);
 
188
                }
 
189
 
 
190
                /// <summary>Does the requested object exist in this database?</summary>
 
191
                /// <param name="objectId">identity of the object to test for existence of.</param>
 
192
                /// <param name="typeHint">
 
193
                /// hint about the type of object being requested;
 
194
                /// <see cref="OBJ_ANY">OBJ_ANY</see>
 
195
                /// if the object type is not known, or does not
 
196
                /// matter to the caller.
 
197
                /// </param>
 
198
                /// <returns>true if the specified object is stored in this database.</returns>
 
199
                /// <exception cref="NGit.Errors.IncorrectObjectTypeException">
 
200
                /// typeHint was not OBJ_ANY, and the object's actual type does
 
201
                /// not match typeHint.
 
202
                /// </exception>
 
203
                /// <exception cref="System.IO.IOException">the object store cannot be accessed.</exception>
 
204
                public virtual bool Has(AnyObjectId objectId, int typeHint)
 
205
                {
 
206
                        try
 
207
                        {
 
208
                                Open(objectId, typeHint);
 
209
                                return true;
 
210
                        }
 
211
                        catch (MissingObjectException)
 
212
                        {
 
213
                                return false;
 
214
                        }
 
215
                }
 
216
 
 
217
                /// <summary>Open an object from this database.</summary>
 
218
                /// <remarks>Open an object from this database.</remarks>
 
219
                /// <param name="objectId">identity of the object to open.</param>
 
220
                /// <returns>
 
221
                /// a
 
222
                /// <see cref="ObjectLoader">ObjectLoader</see>
 
223
                /// for accessing the object.
 
224
                /// </returns>
 
225
                /// <exception cref="NGit.Errors.MissingObjectException">the object does not exist.</exception>
 
226
                /// <exception cref="System.IO.IOException">the object store cannot be accessed.</exception>
 
227
                public virtual ObjectLoader Open(AnyObjectId objectId)
 
228
                {
 
229
                        return Open(objectId, OBJ_ANY);
 
230
                }
 
231
 
 
232
                /// <summary>Open an object from this database.</summary>
 
233
                /// <remarks>Open an object from this database.</remarks>
 
234
                /// <param name="objectId">identity of the object to open.</param>
 
235
                /// <param name="typeHint">
 
236
                /// hint about the type of object being requested;
 
237
                /// <see cref="OBJ_ANY">OBJ_ANY</see>
 
238
                /// if the object type is not known, or does not
 
239
                /// matter to the caller.
 
240
                /// </param>
 
241
                /// <returns>
 
242
                /// a
 
243
                /// <see cref="ObjectLoader">ObjectLoader</see>
 
244
                /// for accessing the object.
 
245
                /// </returns>
 
246
                /// <exception cref="NGit.Errors.MissingObjectException">the object does not exist.</exception>
 
247
                /// <exception cref="NGit.Errors.IncorrectObjectTypeException">
 
248
                /// typeHint was not OBJ_ANY, and the object's actual type does
 
249
                /// not match typeHint.
 
250
                /// </exception>
 
251
                /// <exception cref="System.IO.IOException">the object store cannot be accessed.</exception>
 
252
                public abstract ObjectLoader Open(AnyObjectId objectId, int typeHint);
 
253
 
 
254
                /// <summary>Asynchronous object opening.</summary>
 
255
                /// <remarks>Asynchronous object opening.</remarks>
 
256
                /// <?></?>
 
257
                /// <param name="objectIds">
 
258
                /// objects to open from the object store. The supplied collection
 
259
                /// must not be modified until the queue has finished.
 
260
                /// </param>
 
261
                /// <param name="reportMissing">
 
262
                /// if true missing objects are reported by calling failure with a
 
263
                /// MissingObjectException. This may be more expensive for the
 
264
                /// implementation to guarantee. If false the implementation may
 
265
                /// choose to report MissingObjectException, or silently skip over
 
266
                /// the object with no warning.
 
267
                /// </param>
 
268
                /// <returns>queue to read the objects from.</returns>
 
269
                public virtual AsyncObjectLoaderQueue<T> Open<T>(Iterable<T> objectIds, bool reportMissing
 
270
                        ) where T:ObjectId
 
271
                {
 
272
                        Iterator<T> idItr = objectIds.Iterator();
 
273
                        return new _AsyncObjectLoaderQueue_272<T>(this, idItr);
 
274
                }
 
275
 
 
276
                private sealed class _AsyncObjectLoaderQueue_272<T> : AsyncObjectLoaderQueue<T> where T:ObjectId
 
277
                {
 
278
                        public _AsyncObjectLoaderQueue_272(ObjectReader _enclosing, Iterator<T> idItr)
 
279
                        {
 
280
                                this._enclosing = _enclosing;
 
281
                                this.idItr = idItr;
 
282
                        }
 
283
 
 
284
                        private T cur;
 
285
 
 
286
                        /// <exception cref="NGit.Errors.MissingObjectException"></exception>
 
287
                        /// <exception cref="System.IO.IOException"></exception>
 
288
                        public bool Next()
 
289
                        {
 
290
                                if (idItr.HasNext())
 
291
                                {
 
292
                                        this.cur = idItr.Next();
 
293
                                        return true;
 
294
                                }
 
295
                                else
 
296
                                {
 
297
                                        return false;
 
298
                                }
 
299
                        }
 
300
 
 
301
                        public T GetCurrent()
 
302
                        {
 
303
                                return this.cur;
 
304
                        }
 
305
 
 
306
                        public ObjectId GetObjectId()
 
307
                        {
 
308
                                return this.cur;
 
309
                        }
 
310
 
 
311
                        /// <exception cref="System.IO.IOException"></exception>
 
312
                        public ObjectLoader Open()
 
313
                        {
 
314
                                return this._enclosing.Open(this.cur, ObjectReader.OBJ_ANY);
 
315
                        }
 
316
 
 
317
                        public bool Cancel(bool mayInterruptIfRunning)
 
318
                        {
 
319
                                return true;
 
320
                        }
 
321
 
 
322
                        public void Release()
 
323
                        {
 
324
                        }
 
325
 
 
326
                        private readonly ObjectReader _enclosing;
 
327
 
 
328
                        private readonly Iterator<T> idItr;
 
329
                }
 
330
 
 
331
                // Since we are sequential by default, we don't
 
332
                // have any state to clean up if we terminate early.
 
333
                /// <summary>Get only the size of an object.</summary>
 
334
                /// <remarks>
 
335
                /// Get only the size of an object.
 
336
                /// <p>
 
337
                /// The default implementation of this method opens an ObjectLoader.
 
338
                /// Databases are encouraged to override this if a faster access method is
 
339
                /// available to them.
 
340
                /// </remarks>
 
341
                /// <param name="objectId">identity of the object to open.</param>
 
342
                /// <param name="typeHint">
 
343
                /// hint about the type of object being requested;
 
344
                /// <see cref="OBJ_ANY">OBJ_ANY</see>
 
345
                /// if the object type is not known, or does not
 
346
                /// matter to the caller.
 
347
                /// </param>
 
348
                /// <returns>size of object in bytes.</returns>
 
349
                /// <exception cref="NGit.Errors.MissingObjectException">the object does not exist.</exception>
 
350
                /// <exception cref="NGit.Errors.IncorrectObjectTypeException">
 
351
                /// typeHint was not OBJ_ANY, and the object's actual type does
 
352
                /// not match typeHint.
 
353
                /// </exception>
 
354
                /// <exception cref="System.IO.IOException">the object store cannot be accessed.</exception>
 
355
                public virtual long GetObjectSize(AnyObjectId objectId, int typeHint)
 
356
                {
 
357
                        return Open(objectId, typeHint).GetSize();
 
358
                }
 
359
 
 
360
                /// <summary>Asynchronous object size lookup.</summary>
 
361
                /// <remarks>Asynchronous object size lookup.</remarks>
 
362
                /// <?></?>
 
363
                /// <param name="objectIds">
 
364
                /// objects to get the size of from the object store. The supplied
 
365
                /// collection must not be modified until the queue has finished.
 
366
                /// </param>
 
367
                /// <param name="reportMissing">
 
368
                /// if true missing objects are reported by calling failure with a
 
369
                /// MissingObjectException. This may be more expensive for the
 
370
                /// implementation to guarantee. If false the implementation may
 
371
                /// choose to report MissingObjectException, or silently skip over
 
372
                /// the object with no warning.
 
373
                /// </param>
 
374
                /// <returns>queue to read object sizes from.</returns>
 
375
                public virtual AsyncObjectSizeQueue<T> GetObjectSize<T>(Iterable<T> objectIds, bool
 
376
                         reportMissing) where T:ObjectId
 
377
                {
 
378
                        Iterator<T> idItr = objectIds.Iterator();
 
379
                        return new _AsyncObjectSizeQueue_354<T>(this, idItr);
 
380
                }
 
381
 
 
382
                private sealed class _AsyncObjectSizeQueue_354<T>: AsyncObjectSizeQueue<T> where T:ObjectId
 
383
                {
 
384
                        public _AsyncObjectSizeQueue_354(ObjectReader _enclosing, Iterator<T> idItr)
 
385
                        {
 
386
                                this._enclosing = _enclosing;
 
387
                                this.idItr = idItr;
 
388
                        }
 
389
 
 
390
                        private T cur;
 
391
 
 
392
                        private long sz;
 
393
 
 
394
                        /// <exception cref="NGit.Errors.MissingObjectException"></exception>
 
395
                        /// <exception cref="System.IO.IOException"></exception>
 
396
                        public bool Next()
 
397
                        {
 
398
                                if (idItr.HasNext())
 
399
                                {
 
400
                                        this.cur = idItr.Next();
 
401
                                        this.sz = this._enclosing.GetObjectSize(this.cur, ObjectReader.OBJ_ANY);
 
402
                                        return true;
 
403
                                }
 
404
                                else
 
405
                                {
 
406
                                        return false;
 
407
                                }
 
408
                        }
 
409
 
 
410
                        public T GetCurrent()
 
411
                        {
 
412
                                return this.cur;
 
413
                        }
 
414
 
 
415
                        public ObjectId GetObjectId()
 
416
                        {
 
417
                                return this.cur;
 
418
                        }
 
419
 
 
420
                        public long GetSize()
 
421
                        {
 
422
                                return this.sz;
 
423
                        }
 
424
 
 
425
                        public bool Cancel(bool mayInterruptIfRunning)
 
426
                        {
 
427
                                return true;
 
428
                        }
 
429
 
 
430
                        public void Release()
 
431
                        {
 
432
                        }
 
433
 
 
434
                        private readonly ObjectReader _enclosing;
 
435
 
 
436
                        private readonly Iterator<T> idItr;
 
437
                }
 
438
 
 
439
                // Since we are sequential by default, we don't
 
440
                // have any state to clean up if we terminate early.
 
441
                /// <summary>
 
442
                /// Advice from a
 
443
                /// <see cref="NGit.Revwalk.RevWalk">NGit.Revwalk.RevWalk</see>
 
444
                /// that a walk is starting from these roots.
 
445
                /// </summary>
 
446
                /// <param name="walk">the revision pool that is using this reader.</param>
 
447
                /// <param name="roots">
 
448
                /// starting points of the revision walk. The starting points have
 
449
                /// their headers parsed, but might be missing bodies.
 
450
                /// </param>
 
451
                /// <exception cref="System.IO.IOException">the reader cannot initialize itself to support the walk.
 
452
                ///     </exception>
 
453
                public virtual void WalkAdviceBeginCommits(RevWalk walk, ICollection<RevCommit> roots
 
454
                        )
 
455
                {
 
456
                }
 
457
 
 
458
                // Do nothing by default, most readers don't want or need advice.
 
459
                /// <summary>
 
460
                /// Advice from an
 
461
                /// <see cref="NGit.Revwalk.ObjectWalk">NGit.Revwalk.ObjectWalk</see>
 
462
                /// that trees will be traversed.
 
463
                /// </summary>
 
464
                /// <param name="ow">the object pool that is using this reader.</param>
 
465
                /// <param name="min">the first commit whose root tree will be read.</param>
 
466
                /// <param name="max">the last commit whose root tree will be read.</param>
 
467
                /// <exception cref="System.IO.IOException">the reader cannot initialize itself to support the walk.
 
468
                ///     </exception>
 
469
                public virtual void WalkAdviceBeginTrees(ObjectWalk ow, RevCommit min, RevCommit 
 
470
                        max)
 
471
                {
 
472
                }
 
473
 
 
474
                // Do nothing by default, most readers don't want or need advice.
 
475
                /// <summary>Advice from that a walk is over.</summary>
 
476
                /// <remarks>Advice from that a walk is over.</remarks>
 
477
                public virtual void WalkAdviceEnd()
 
478
                {
 
479
                }
 
480
 
 
481
                // Do nothing by default, most readers don't want or need advice.
 
482
                /// <summary>Release any resources used by this reader.</summary>
 
483
                /// <remarks>
 
484
                /// Release any resources used by this reader.
 
485
                /// <p>
 
486
                /// A reader that has been released can be used again, but may need to be
 
487
                /// released after the subsequent usage.
 
488
                /// </remarks>
 
489
                public virtual void Release()
 
490
                {
 
491
                }
 
492
                // Do nothing.
 
493
        }
 
494
}