123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- /*
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Distribution License v. 1.0 which is available at
- * https://www.eclipse.org/org/documents/edl-v10.php.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
- package org.eclipse.jgit.internal.storage.file;
-
- import java.lang.ref.SoftReference;
-
- import org.eclipse.jgit.storage.file.WindowCacheConfig;
-
- class DeltaBaseCache {
- private static final int CACHE_SZ = 1024;
-
- static final SoftReference<Entry> DEAD;
-
- private static int hash(long position) {
- return (((int) position) << 22) >>> 22;
- }
-
- private static volatile int defaultMaxByteCount;
-
- private final int maxByteCount;
-
- private final Slot[] cache;
-
- private Slot lruHead;
-
- private Slot lruTail;
-
- private int openByteCount;
-
- static {
- DEAD = new SoftReference<>(null);
- reconfigure(new WindowCacheConfig());
- }
-
- static void reconfigure(WindowCacheConfig cfg) {
- defaultMaxByteCount = cfg.getDeltaBaseCacheLimit();
- }
-
- DeltaBaseCache() {
- maxByteCount = defaultMaxByteCount;
- cache = new Slot[CACHE_SZ];
- }
-
- Entry get(Pack pack, long position) {
- Slot e = cache[hash(position)];
- if (e == null)
- return null;
- if (e.provider == pack && e.position == position) {
- final Entry buf = e.data.get();
- if (buf != null) {
- moveToHead(e);
- return buf;
- }
- }
- return null;
- }
-
- void store(final Pack pack, final long position,
- final byte[] data, final int objectType) {
- if (data.length > maxByteCount)
- return; // Too large to cache.
-
- Slot e = cache[hash(position)];
- if (e == null) {
- e = new Slot();
- cache[hash(position)] = e;
- } else {
- clearEntry(e);
- }
-
- openByteCount += data.length;
- releaseMemory();
-
- e.provider = pack;
- e.position = position;
- e.sz = data.length;
- e.data = new SoftReference<>(new Entry(data, objectType));
- moveToHead(e);
- }
-
- private void releaseMemory() {
- while (openByteCount > maxByteCount && lruTail != null) {
- final Slot currOldest = lruTail;
- final Slot nextOldest = currOldest.lruPrev;
-
- clearEntry(currOldest);
- currOldest.lruPrev = null;
- currOldest.lruNext = null;
-
- if (nextOldest == null)
- lruHead = null;
- else
- nextOldest.lruNext = null;
- lruTail = nextOldest;
- }
- }
-
- private void moveToHead(Slot e) {
- unlink(e);
- e.lruPrev = null;
- e.lruNext = lruHead;
- if (lruHead != null)
- lruHead.lruPrev = e;
- else
- lruTail = e;
- lruHead = e;
- }
-
- private void unlink(Slot e) {
- final Slot prev = e.lruPrev;
- final Slot next = e.lruNext;
- if (prev != null)
- prev.lruNext = next;
- if (next != null)
- next.lruPrev = prev;
- }
-
- private void clearEntry(Slot e) {
- openByteCount -= e.sz;
- e.provider = null;
- e.data = DEAD;
- e.sz = 0;
- }
-
- static class Entry {
- final byte[] data;
-
- final int type;
-
- Entry(byte[] aData, int aType) {
- data = aData;
- type = aType;
- }
- }
-
- private static class Slot {
- Slot lruPrev;
-
- Slot lruNext;
-
- Pack provider;
-
- long position;
-
- int sz;
-
- SoftReference<Entry> data = DEAD;
- }
- }
|