You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DeltaBaseCache.java 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
  3. *
  4. * This program and the accompanying materials are made available under the
  5. * terms of the Eclipse Distribution License v. 1.0 which is available at
  6. * https://www.eclipse.org/org/documents/edl-v10.php.
  7. *
  8. * SPDX-License-Identifier: BSD-3-Clause
  9. */
  10. package org.eclipse.jgit.internal.storage.file;
  11. import java.lang.ref.SoftReference;
  12. import org.eclipse.jgit.storage.file.WindowCacheConfig;
  13. class DeltaBaseCache {
  14. private static final int CACHE_SZ = 1024;
  15. static final SoftReference<Entry> DEAD;
  16. private static int hash(long position) {
  17. return (((int) position) << 22) >>> 22;
  18. }
  19. private static volatile int defaultMaxByteCount;
  20. private final int maxByteCount;
  21. private final Slot[] cache;
  22. private Slot lruHead;
  23. private Slot lruTail;
  24. private int openByteCount;
  25. static {
  26. DEAD = new SoftReference<>(null);
  27. reconfigure(new WindowCacheConfig());
  28. }
  29. static void reconfigure(WindowCacheConfig cfg) {
  30. defaultMaxByteCount = cfg.getDeltaBaseCacheLimit();
  31. }
  32. DeltaBaseCache() {
  33. maxByteCount = defaultMaxByteCount;
  34. cache = new Slot[CACHE_SZ];
  35. }
  36. Entry get(Pack pack, long position) {
  37. Slot e = cache[hash(position)];
  38. if (e == null)
  39. return null;
  40. if (e.provider == pack && e.position == position) {
  41. final Entry buf = e.data.get();
  42. if (buf != null) {
  43. moveToHead(e);
  44. return buf;
  45. }
  46. }
  47. return null;
  48. }
  49. void store(final Pack pack, final long position,
  50. final byte[] data, final int objectType) {
  51. if (data.length > maxByteCount)
  52. return; // Too large to cache.
  53. Slot e = cache[hash(position)];
  54. if (e == null) {
  55. e = new Slot();
  56. cache[hash(position)] = e;
  57. } else {
  58. clearEntry(e);
  59. }
  60. openByteCount += data.length;
  61. releaseMemory();
  62. e.provider = pack;
  63. e.position = position;
  64. e.sz = data.length;
  65. e.data = new SoftReference<>(new Entry(data, objectType));
  66. moveToHead(e);
  67. }
  68. private void releaseMemory() {
  69. while (openByteCount > maxByteCount && lruTail != null) {
  70. final Slot currOldest = lruTail;
  71. final Slot nextOldest = currOldest.lruPrev;
  72. clearEntry(currOldest);
  73. currOldest.lruPrev = null;
  74. currOldest.lruNext = null;
  75. if (nextOldest == null)
  76. lruHead = null;
  77. else
  78. nextOldest.lruNext = null;
  79. lruTail = nextOldest;
  80. }
  81. }
  82. private void moveToHead(Slot e) {
  83. unlink(e);
  84. e.lruPrev = null;
  85. e.lruNext = lruHead;
  86. if (lruHead != null)
  87. lruHead.lruPrev = e;
  88. else
  89. lruTail = e;
  90. lruHead = e;
  91. }
  92. private void unlink(Slot e) {
  93. final Slot prev = e.lruPrev;
  94. final Slot next = e.lruNext;
  95. if (prev != null)
  96. prev.lruNext = next;
  97. if (next != null)
  98. next.lruPrev = prev;
  99. }
  100. private void clearEntry(Slot e) {
  101. openByteCount -= e.sz;
  102. e.provider = null;
  103. e.data = DEAD;
  104. e.sz = 0;
  105. }
  106. static class Entry {
  107. final byte[] data;
  108. final int type;
  109. Entry(byte[] aData, int aType) {
  110. data = aData;
  111. type = aType;
  112. }
  113. }
  114. private static class Slot {
  115. Slot lruPrev;
  116. Slot lruNext;
  117. Pack provider;
  118. long position;
  119. int sz;
  120. SoftReference<Entry> data = DEAD;
  121. }
  122. }