2 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
6 * Redistribution and use in source and binary forms, with or
7 * without modification, are permitted provided that the following
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * - Neither the name of the Git Development Community nor the
19 * names of its contributors may be used to endorse or promote
20 * products derived from this software without specific prior
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
24 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 package org
.spearce
.jgit
.lib
;
40 import java
.lang
.ref
.SoftReference
;
42 class UnpackedObjectCache
{
43 private static final int CACHE_SZ
= 256;
45 private static final int MB
= 1024 * 1024;
47 private static final SoftReference
<Entry
> DEAD
;
49 private static int hash(final WindowedFile pack
, final long position
) {
50 int h
= pack
.hash
+ (int) position
;
56 private static int maxByteCount
;
58 private static final Slot
[] cache
;
60 private static Slot lruHead
;
62 private static Slot lruTail
;
64 private static int openByteCount
;
67 DEAD
= new SoftReference
<Entry
>(null);
68 maxByteCount
= 10 * MB
;
70 cache
= new Slot
[CACHE_SZ
];
71 for (int i
= 0; i
< CACHE_SZ
; i
++)
72 cache
[i
] = new Slot();
75 static synchronized void reconfigure(final int dbLimit
) {
76 if (maxByteCount
!= dbLimit
) {
77 maxByteCount
= dbLimit
;
82 static synchronized Entry
get(final WindowedFile pack
, final long position
) {
83 final Slot e
= cache
[hash(pack
, position
)];
84 if (e
.provider
== pack
&& e
.position
== position
) {
85 final Entry buf
= e
.data
.get();
94 static synchronized void store(final WindowedFile pack
,
95 final long position
, final byte[] data
, final int objectType
) {
96 if (data
.length
> maxByteCount
)
97 return; // Too large to cache.
99 final Slot e
= cache
[hash(pack
, position
)];
102 openByteCount
+= data
.length
;
106 e
.position
= position
;
107 e
.data
= new SoftReference
<Entry
>(new Entry(data
, objectType
));
111 private static void releaseMemory() {
112 while (openByteCount
> maxByteCount
&& lruTail
!= null) {
113 final Slot currOldest
= lruTail
;
114 final Slot nextOldest
= currOldest
.lruPrev
;
116 clearEntry(currOldest
);
117 currOldest
.lruPrev
= null;
118 currOldest
.lruNext
= null;
120 if (nextOldest
== null)
123 nextOldest
.lruNext
= null;
124 lruTail
= nextOldest
;
128 static synchronized void purge(final WindowedFile file
) {
129 for (final Slot e
: cache
) {
130 if (e
.provider
== file
) {
137 private static void moveToHead(final Slot e
) {
148 private static void unlink(final Slot e
) {
149 final Slot prev
= e
.lruPrev
;
150 final Slot next
= e
.lruNext
;
157 private static void clearEntry(final Slot e
) {
158 final Entry old
= e
.data
.get();
160 openByteCount
-= old
.data
.length
;
165 private UnpackedObjectCache() {
166 throw new UnsupportedOperationException();
174 Entry(final byte[] aData
, final int aType
) {
180 private static class Slot
{
185 WindowedFile provider
;
189 SoftReference
<Entry
> data
= DEAD
;