BlockObjQueue.java

  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.revwalk;

  11. class BlockObjQueue {
  12.     private BlockFreeList free;

  13.     private Block head;

  14.     private Block tail;

  15.     /** Create an empty queue. */
  16.     BlockObjQueue() {
  17.         free = new BlockFreeList();
  18.     }

  19.     void add(RevObject c) {
  20.         Block b = tail;
  21.         if (b == null) {
  22.             b = free.newBlock();
  23.             b.add(c);
  24.             head = b;
  25.             tail = b;
  26.             return;
  27.         } else if (b.isFull()) {
  28.             b = free.newBlock();
  29.             tail.next = b;
  30.             tail = b;
  31.         }
  32.         b.add(c);
  33.     }

  34.     RevObject next() {
  35.         final Block b = head;
  36.         if (b == null)
  37.             return null;

  38.         final RevObject c = b.pop();
  39.         if (b.isEmpty()) {
  40.             head = b.next;
  41.             if (head == null)
  42.                 tail = null;
  43.             free.freeBlock(b);
  44.         }
  45.         return c;
  46.     }

  47.     static final class BlockFreeList {
  48.         private Block next;

  49.         Block newBlock() {
  50.             Block b = next;
  51.             if (b == null)
  52.                 return new Block();
  53.             next = b.next;
  54.             b.clear();
  55.             return b;
  56.         }

  57.         void freeBlock(Block b) {
  58.             b.next = next;
  59.             next = b;
  60.         }
  61.     }

  62.     static final class Block {
  63.         private static final int BLOCK_SIZE = 256;

  64.         /** Next block in our chain of blocks; null if we are the last. */
  65.         Block next;

  66.         /** Our table of queued objects. */
  67.         final RevObject[] objects = new RevObject[BLOCK_SIZE];

  68.         /** Next valid entry in {@link #objects}. */
  69.         int headIndex;

  70.         /** Next free entry in {@link #objects} for addition at. */
  71.         int tailIndex;

  72.         boolean isFull() {
  73.             return tailIndex == BLOCK_SIZE;
  74.         }

  75.         boolean isEmpty() {
  76.             return headIndex == tailIndex;
  77.         }

  78.         void add(RevObject c) {
  79.             objects[tailIndex++] = c;
  80.         }

  81.         RevObject pop() {
  82.             return objects[headIndex++];
  83.         }

  84.         void clear() {
  85.             next = null;
  86.             headIndex = 0;
  87.             tailIndex = 0;
  88.         }
  89.     }
  90. }