text:
import React from "react";
import { Room } from "matrix-js-sdk/src/models/room";
import { CSSTransition } from "react-transition-group";

import { BreadcrumbsStore } from "../../../stores/BreadcrumbsStore";
import DecoratedRoomAvatar from "../avatars/DecoratedRoomAvatar";
import { _t } from "../../../languageHandler";
import defaultDispatcher from "../../../dispatcher/dispatcher";
import { UPDATE_EVENT } from "../../../stores/AsyncStore";
import { useRovingTabIndex } from "../../../accessibility/RovingTabIndex";
import Toolbar from "../../../accessibility/Toolbar";
import { Action } from "../../../dispatcher/actions";
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
import { ButtonEvent } from "../elements/AccessibleButton";

interface IProps {
}

interface IState {
    // Both of these control the animation for the breadcrumbs. For details on the
    // actual animation, see the CSS.
    //
    // doAnimation is to lie to the CSSTransition component (see onBreadcrumbsUpdate
    // for info). skipFirst is used to try and reduce jerky animation - also see the
    // breadcrumb update function for info on that.
    doAnimation: boolean;
    skipFirst: boolean;
}

const RoomBreadcrumbTile = ({ room, onClick }: { room: Room, onClick: (ev: ButtonEvent) => void }) => {
    const [onFocus, isActive, ref] = useRovingTabIndex();

    return (
        <AccessibleTooltipButton
            className="mx_RoomBreadcrumbs_crumb"
            onClick={onClick}
            aria-label={_t("Room %(name)s", { name: room.name })}
            title={room.name}
            tooltipClassName="mx_RoomBreadcrumbs_Tooltip"
            onFocus={onFocus}
            inputRef={ref}
            tabIndex={isActive ? 0 : -1}
        >
            <DecoratedRoomAvatar
                room={room}
                avatarSize={32}
                displayBadge={true}
                forceCount={true}
                tooltipProps={{ tabIndex: isActive ? 0 : -1 }}
            />
        </AccessibleTooltipButton>
    );
};

export default class RoomBreadcrumbs extends React.PureComponent<IProps, IState> {
    private isMounted = true;

    constructor(props: IProps) {
        super(props);

        this.state = {
            doAnimation: true, // technically we want animation on mount, but it won't be perfect
            skipFirst: false, // render the thing, as boring as it is
        };

        BreadcrumbsStore.instance.on(UPDATE_EVENT, this.onBreadcrumbsUpdate);
    }

    public componentWillUnmount() {
        this.isMounted = false;
        BreadcrumbsStore.instance.off(UPDATE_EVENT, this.onBreadcrumbsUpdate);
    }

    private onBreadcrumbsUpdate = () => {
        if (!this.isMounted) return;

        // We need to trick the CSSTransition component into updating, which means we need to
        // tell it to not animate, then to animate a moment later. This causes two updates
        // which means two renders. The skipFirst change is so that our don't-animate state
        // doesn't show the breadcrumb we're about to reveal as it causes a visual jump/jerk.
        // The second update, on the next available tick, causes the "enter" animation to start
        // again and this time we want to show the newest breadcrumb because it'll be hidden
        // off screen for the animation.
        this.setState({ doAnimation: false, skipFirst: true });
        setTimeout(() => this.setState({ doAnimation: true, skipFirst: false }), 0);
    };

    private viewRoom = (room: Room, index: number, viaKeyboard = false) => {
        defaultDispatcher.dispatch<ViewRoomPayload>({
            action: Action.ViewRoom,
            room_id: room.roomId,
            metricsTrigger: "WebHorizontalBreadcrumbs",
            metricsViaKeyboard: viaKeyboard,
        });
    };

    public render(): React.ReactElement {
        const tiles = BreadcrumbsStore.instance.rooms.map((r, i) => (
            <RoomBreadcrumbTile
                key={r.roomId}
                room={r}
                onClick={(ev: ButtonEvent) => this.viewRoom(r, i, ev.type !== "click")}
            />
        ));

        if (tiles.length > 0) {
            // NOTE: The CSSTransition timeout MUST match the timeout in our CSS!
            return (
                <CSSTransition
                    appear={true}
                    in={this.state.doAnimation}
                    timeout={640}
                    classNames='mx_RoomBreadcrumbs'
                >
                    <Toolbar className='mx_RoomBreadcrumbs' aria-label={_t("Recently visited rooms")}>
                        { tiles.slice(this.state.skipFirst ? 1 : 0) }
                    </Toolbar>
                </CSSTransition>
            );
        } else {
            return (

                        { _t("No recently visited rooms") }

            );
        }
    }
}


text:
from django.conf.urls import patterns, include, url
import settings
import notification
import users
# Uncomment the next two lines to enable the admin:
# from django.contrib import admin
# admin.autodiscover()

urlpatterns = patterns('',
	url(r'^notifyCenter$', 'notification.views.main', name='main'),
	url(r'^static/(?P<path>.*)$','django.views.static.serve',{'document_root':settings.STATIC_URL},name='static'),
    url(r'^notify$','notification.views.notification', name='notification'),
    url(r'^start$','notification.views.start', name='start'),

    url(r'^users$','users.views.getUser',name='getuser'),
    # Examples:
    # url(r'^$', 'PushNotify.views.home', name='home'),
    # url(r'^PushNotify/', include('PushNotify.foo.urls')),

    # Uncomment the admin/doc line below to enable admin documentation:
    # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    # url(r'^admin/', include(admin.site.urls)),
)

redpajama_set_name: RedPajamaGithub


text:
package com.yummynoodlebar.core.events.orders;

import com.yummynoodlebar.core.events.DeleteEvent;

import java.util.UUID;

public class DeleteOrderEvent extends DeleteEvent {

  private final UUID key;

  public DeleteOrderEvent(final UUID key) {
    this.key = key;
  }

  public UUID getKey() {
    return key;
  }
}


text:
import React from "react";
import { render, fireEvent } from "@testing-library/react";
import { Button, Type, HtmlType, Size } from "..";
import { overrideError } from "@src/utils";

let recoverError: null | Function = null;
beforeAll(() => {
  recoverError = overrideError();
});
afterAll(() => {
  if (typeof recoverError === "function") {
    recoverError();
  }
});

const cleanUp = () => (document.body.innerHTML = "");

describe("Button", () => {
  test("handle className properly", () => {
    const { getByText } = render(<Button className="button">button</Button>);
    expect(getByText("button").classList.contains("button")).toBe(true);
  });

  test("handle 'type' properly", () => {
    const acceptableTypes: Type[] = ["primary", "default", "warning", "danger"];
    acceptableTypes.forEach(type => {
      const { getByText } = render(<Button type={type}>button</Button>);
      expect(getByText("button").classList.contains(`c-button--${type}`)).toBe(
        true
      );
      cleanUp();
    });
  });

  test("won't add additional class for incorrect 'type'", () => {
    const type: string = "a";
    // @ts-ignore
    const { getByText } = render(<Button type={type}>type</Button>);
    expect(getByText("type").classList.contains(`c-button--${type}`)).toBe(
      false
    );
  });

  test("handle 'size' properly", () => {
    const acceptableSizes: Size[] = ["large", "normal", "small"];
    acceptableSizes.forEach(size => {
      const { getByText } = render(<Button size={size}>size</Button>);
      expect(getByText("size").classList.contains(`c-button--${size}`)).toBe(
        true
      );
      cleanUp();
    });
  });

  test("won't add additional class for incorrect 'size'", () => {
    const size: string = "a";
    // @ts-ignore
    const { getByText } = render(<Button size={size}>size</Button>);
    expect(getByText("size").classList.contains(`c-button--${size}`)).toBe(
      false
    );
  });

  test("handle 'htmlType' properly", () => {
    const acceptableHtmlTypes: HtmlType[] = ["button", "reset", "submit"];
    acceptableHtmlTypes.forEach(htmlType => {
      const { getByText } = render(<Button htmlType={htmlType}>html</Button>);
      expect(getByText("html").getAttribute("type") === htmlType).toBe(true);
      cleanUp();
    });
  });

  test("handle 'block' properly", () => {
    const { getByText } = render(<Button>normal</Button>);
    expect(getByText("normal").classList.contains("c-button--block")).toBe(
      false
    );
    const { getByText: blockGetByText } = render(<Button block>block</Button>);
    expect(blockGetByText("block").classList.contains("c-button--block")).toBe(
      true
    );
  });

  test("handle 'loading' properly", () => {
    const { getByText } = render(<Button>normal</Button>);
    expect(getByText("normal").classList.contains("c-button--loading")).toBe(
      false
    );
    const { getByText: loadingGetByText } = render(
      <Button loading>loading</Button>
    );
    expect(
      loadingGetByText("loading").classList.contains("c-button--loading")
    ).toBe(true);
  });

  test("handle 'disabled' properly", () => {
    const { getByText } = render(<Button>normal</Button>);
    expect((getByText("normal") as HTMLButtonElement).disabled).toBe(false);
    const { getByText: disabledGetByText } = render(
      <Button disabled>disabled</Button>
    );
    expect((disabledGetByText("disabled") as HTMLButtonElement).disabled).toBe(
      true
    );
  });

  test("handle event properly", () => {
    const textContent: string = "button";
    const callBack = (e: React.MouseEvent) =>
      expect((e.target as HTMLButtonElement).textContent).toBe(textContent);
    const events = {
      onClick: callBack,
      onSubmit: callBack,
      onReset: callBack
    };
    const { getByText } = render(<Button {...events}>{textContent}</Button>);
    fireEvent.click(getByText(textContent));
    cleanUp();
    const { getByText: submitGetByText } = render(
      <Button {...events} htmlType="submit">
        {textContent}
      </Button>
    );
    fireEvent.submit(submitGetByText(textContent));
    cleanUp();
    const { getByText: resetGetByText } = render(
      <Button {...events} htmlType="reset">
        {textContent}
      </Button>
    );
    fireEvent(resetGetByText(textContent), new Event("reset"));
  });
});


text:
module Perfer
  class IterationJob < Job
    # This factor ensure some margin,
    # to avoid endlessly changing the number of iterations
    CHANGE_ITERATIONS_MARGIN = 0.1
    MAX_GROW_FACTOR = 10
    UNIQUE_NAME = "a"

    def repeat_eval
      100
    end

    def initialize(session, title, code = nil, data = nil, &block)
      super(session, title, &block)
      load_metadata
      compile_method(code, data) if code and !block
    end

    def compile_method(code, data)
      @data = data || {}
      if obj = @data.delete(:self)
        klass = obj.singleton_class
        meth = generate_method_name
      else
        klass = singleton_class
        meth = :measure_call_times_code
      end

      if klass.method_defined?(meth)
        raise Error, "method #{meth} already defined on #{klass} (#{obj})!"
      end

      begin
        klass.class_eval <<-EOR
        def #{meth}(__n#{@data.keys.map { |k| ", #{k}" }.join})
          ::Perfer.measure do
            __i = 0
            while __i < __n
              #{"#{code}; " * repeat_eval}
              __i += 1
            end
          end
        end
        EOR
      rescue SyntaxError => e
        raise Error, "There was an error while eval'ing the code: #{code.inspect}\n#{e}"
      end

      if obj
        singleton_class.send(:define_method, :measure_call_times_code) do |*args|
          obj.send(meth, *args)
        end
      end
    end

    def generate_method_name
      :"perfer_eval_#{UNIQUE_NAME.succ!}"
    end

    def measure_call_times(n)
      GC.start
      if !@block
        if n % repeat_eval != 0
          raise Error, "Implementation error: #{n} not multiple of #{repeat_eval}"
        end
        n /= repeat_eval
        measure_call_times_code(n, *@data.values)
      else
        Perfer.measure { n.times(&@block) }
      end.tap { |m| p m if verbose }
    end

    def round_for_eval(iterations)
      if @block
        iterations
      else
        ((iterations + repeat_eval - 1) / repeat_eval) * repeat_eval
      end
    end

    def compute_new_iterations(iterations, time)
      (minimal_time * iterations / time).ceil
    end

    def find_number_of_iterations_required(last_iterations = 1, last_time = 0)
      iterations = last_iterations
      if last_time > 0
        iterations = compute_new_iterations(last_iterations, last_time)
      end
      iterations = round_for_eval(iterations)
      puts "Start search for iterations: start=#{iterations}" if verbose
      loop do
        puts "iterations: #{iterations}" if verbose
        time = measure_call_times(iterations)[:real]
        break if time > minimal_time

        if time <= 0
          iterations *= 2
          next
        end

        new_iterations = compute_new_iterations(iterations, time)
        # ensure the number of iterations increases
        if new_iterations <= iterations
          puts "new_iterations <= iterations: #{new_iterations} <= #{iterations}" if verbose
          new_iterations = (iterations*1.5).ceil
        end
        if new_iterations > MAX_GROW_FACTOR * iterations
          new_iterations = MAX_GROW_FACTOR * iterations
        end
        iterations = round_for_eval(new_iterations)
      end
      puts "End search for iterations: iterations=#{iterations}" if verbose
      iterations
    end

    # median absolute deviation / median
    def mad(measurements)
      stats = Statistics.new(measurements.map { |m| m[:real] })
      mad = stats.median_absolute_deviation
      mad /= stats.median
      puts "mad: #{mad}" if verbose
      mad
    end

    def run
      super
      measurements = []

      # Run one iteration, so system-level buffers and other OS warm-up can take place
      # This is usually a very inaccurate measurement, so just discard it
      measure_call_times(round_for_eval(1))

      iterations = find_number_of_iterations_required

      measurements_taken = 0
      until measurements.size == number_of_measurements and
            mad(measurements) < 0.01 * measurements_taken / number_of_measurements
        time = measure_call_times(iterations)
        measurements_taken += 1
        if time[:real] < (1.0 - CHANGE_ITERATIONS_MARGIN) * minimal_time
          # restart and find a more appropriate number of iterations
          puts "Restarting, #{time[:real]} < #{minimal_time}" if verbose
          measurements.clear
          measurements_taken = 0
          iterations = find_number_of_iterations_required(iterations, time[:real])
        else
          # circular buffer needed!
          measurements.shift if measurements.size == number_of_measurements
          measurements << time
        end
      end

      result = Result.new(@metadata)
      result[:iterations] = iterations
      result.data = measurements
      @session.add_result(result)
    end
  end
end


text:
<!DOCTYPE html>

  <meta charset="UTF-8">
  <title>Open River Data Catalog</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" type="text/css" href="stylesheets/normalize.css" media="screen">
  <link href='http://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>
  <link rel="stylesheet" type="text/css" href="stylesheets/stylesheet.css" media="screen">
  <link rel="stylesheet" type="text/css" href="stylesheets/github-light.css" media="screen">

Open River Data Catalog

a fictitious muncipality on PEI

(an example by Open Data Book Club)

About

This is the base Jekyll theme. You can find out more info about customizing your Jekyll theme, as well as basic Jekyll usage documentation at jekyllrb.com

You can find the source code for the Jekyll new theme at: github.com/jglovier/jekyll-new

You can find the source code for Jekyll at github.com/jekyll/jekyll

  This page was derived from OpenDataBook.club


text:
using ConsoleGraphics.Graphics;
using ConsoleGraphics.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleGraphics.Game.UI
{
    class DropDown : UIObject
    {
        public List<Object> Items = new List<object>();
        public bool Dropped = false;

        public DropDown(Space space, Style style)
            : base(space, style)
        {
            space.UIObjects.Add(this);
        }

        public DropDown(UIObject parent, Style style)
            : base(parent, style)
        {
            parent.Children.Add(this);
        }

        public override void Update()
        {
            base.Update();
            if (MouseDown) Dropped = true;
            if (!MouseOver && Mouse.Left) Dropped = true;
        }

        public override void Draw()
        {
            // Body
            if (Style.Filled) Renderer.FillRect(this, 0, 0, Width, 3, Style.BackChar, Style.BackColor);
            if (Style.Border) Renderer.DrawRect(this, 0, 0, Width, 3, Style.ForeChar, Style.ForeColor);
            Renderer.Draw(this, Style.Text, 1, 1, Style.BackColor);

            // DropDown
            if (!Dropped) return;

        }
    }
}


text:
require_relative '../../lib/manageiq/environment'
ManageIQ::Environment.write_region_file
ManageIQ::Environment.ensure_config_files
ManageIQ::Environment.create_database_user


text:
/***********************************************************************/
/*                                                                     */
/*                                OCaml                                */
/*                                                                     */
/*            Xavier Leroy, projet Cristal, INRIA Rocquencourt         */
/*                                                                     */
/*  Copyright 1996 Institut National de Recherche en Informatique et   */
/*  en Automatique.  All rights reserved.  This file is distributed    */
/*  under the terms of the GNU Library General Public License, with    */
/*  the special exception on linking described in file ../LICENSE.     */
/*                                                                     */
/***********************************************************************/

/* The bytecode interpreter */

#ifndef CAML_INTERP_H
#define CAML_INTERP_H

#include "misc.h"
#include "mlvalues.h"

/* interpret a bytecode */
value caml_interprete (code_t prog, asize_t prog_size);

/* tell the runtime that a bytecode program might be needed */
void caml_prepare_bytecode(code_t prog, asize_t prog_size);

/* tell the runtime that a bytecode program is no more needed */
void caml_release_bytecode(code_t prog, asize_t prog_size);

#endif /* CAML_INTERP_H */


text:
Path_xml = uigetdir('', 'where is the xml file?');
File_xml = uigetfile(strcat(Path_xml,'/*.xml'), 'Choose the xml file');
xDoc = xmlread(strcat(Path_xml, '/', File_xml));

% Find all the TotalVolume elements (should only be one).
% The getElementsByTagName method returns
% a deep list that contains information about the child nodes:
TotalVolumeList = xDoc.getElementsByTagName('TotalVolume');
TotalVolumeTag = TotalVolumeList.item(0);
volume = TotalVolumeTag.getFirstChild.getData


text:
module Psych # :nodoc:
  class PrivateType # :nodoc:
  end
end


text:
import * as _ from "../index";
declare module "../index" {
    interface LoDashStatic {
        /**
         * Produces a random number between min and max (inclusive). If only one argument is provided a number between
         * 0 and the given number is returned. If floating is true, or either min or max are floats, a floating-point
         * number is returned instead of an integer.
         *
         * @param min The minimum possible value.
         * @param max The maximum possible value.
         * @param floating Specify returning a floating-point number.
         * @return Returns the random number.
         */
        random(
            floating?: boolean
        ): number;

        /**
         * @see _.random
         */
        random(
            max: number,
            floating?: boolean
        ): number;

        /**
         * @see _.random
         */
        random(
            min: number,
            max: number,
            floating?: boolean
        ): number;

        /**
         * Produces a random number between min and max (inclusive). If only one argument is provided a number between
         * 0 and the given number is returned. If floating is true, or either min or max are floats, a floating-point
         * number is returned instead of an integer.
         *
         * @param min The minimum possible value.
         * @param index Not used in this overload.
         * @param guard Enables use as an iteratee for methods like _.map. You should not pass this parameter directly in your code.
         * @return Returns the random number.
         */
        random(
            min: number,
            index: string | number,
            guard: object
        ): number;
    }

    interface LoDashImplicitWrapper<TValue> {
        /**
         * @see _.random
         */
        random(floating?: boolean): number;

        /**
         * @see _.random
         */
        random(
            max: number,
            floating?: boolean
        ): number;
    }

    interface LoDashExplicitWrapper<TValue> {
        /**
         * @see _.random
         */
        random(floating?: boolean): LoDashExplicitWrapper<number>;

        /**
         * @see _.random
         */
        random(
            max: number,
            floating?: boolean
        ): LoDashExplicitWrapper<number>;
    }

    /**********
     * Object *
     **********/
}


text:
package java.util

class Timer() {
  private[util] var canceled: Boolean = false

  def this(isDaemon: Boolean) = this()

  def this(name: String) = this()

  def this(name: String, isDaemon: Boolean) = this()

  private def acquire(task: TimerTask): Unit = {
    if (canceled)
      throw new IllegalStateException("Timer already cancelled.")
    else if (task.owner != null || task.canceled) {
      throw new IllegalStateException("TimerTask already scheduled or canceled.")
    }
    task.owner = this
  }

  private def checkDelay(delay: Long): Unit = {
    if (delay < 0 || (delay + System.currentTimeMillis()) < 0)
      throw new IllegalArgumentException("Negative delay.")
  }

  private def checkTime(time: Date): Unit = {
    if (time.getTime() < 0)
      throw new IllegalArgumentException(s"Negative time: $time.")
  }

  private def checkPeriod(period: Long): Unit = {
    if (period <= 0)
      throw new IllegalArgumentException("Non-positive period.")
  }

  private def scheduleOnce(task: TimerTask, delay: Long): Unit = {
    acquire(task)
    task.timeout(delay) {
      task.scheduledOnceAndStarted = true
      task.doRun()
    }
  }

  private def getMillisUntil(time: Date): Long =
    Math.max(0L, time.getTime() - System.currentTimeMillis())

  def schedule(task: TimerTask, delay: Long): Unit = {
    checkDelay(delay)
    scheduleOnce(task, delay)
  }

  def schedule(task: TimerTask, time: Date): Unit = {
    checkTime(time)
    val delay = getMillisUntil(time)
    scheduleOnce(task, delay)
  }

  private def schedulePeriodically(
      task: TimerTask, delay: Long, period: Long): Unit = {
    acquire(task)

    def loop(): Unit = {
      val startTime = System.nanoTime()
      task.doRun()
      val endTime = System.nanoTime()
      val duration = (endTime - startTime) / 1000000
      task.timeout(period - duration) {
        loop()
      }
    }

    task.timeout(delay) {
      loop()
    }
  }

  def schedule(task: TimerTask, delay: Long, period: Long): Unit = {
    checkDelay(delay)
    checkPeriod(period)
    schedulePeriodically(task, delay, period)
  }

  def schedule(task: TimerTask, firstTime: Date, period: Long): Unit = {
    checkTime(firstTime)
    checkPeriod(period)
    val delay = getMillisUntil(firstTime)
    schedulePeriodically(task, delay, period)
  }

  private def scheduleFixed(
      task: TimerTask, delay: Long, period: Long): Unit = {
    acquire(task)

    def loop(scheduledTime: Long): Unit = {
      task.doRun()
      val nextScheduledTime = scheduledTime + period
      val nowTime = System.nanoTime() / 1000000L
      if (nowTime >= nextScheduledTime) {
        // Re-run immediately.
        loop(nextScheduledTime)
      } else {
        // Re-run after a timeout.
        task.timeout(nextScheduledTime - nowTime) {
          loop(nextScheduledTime)
        }
      }
    }

    task.timeout(delay) {
      loop(System.nanoTime() / 1000000L + period)
    }
  }

  def scheduleAtFixedRate(task: TimerTask, delay: Long, period: Long): Unit = {
    checkDelay(delay)
    checkPeriod(period)
    scheduleFixed(task, delay, period)
  }

  def scheduleAtFixedRate(task: TimerTask, firstTime: Date, period: Long): Unit = {
    checkTime(firstTime)
    checkPeriod(period)
    val delay = getMillisUntil(firstTime)
    scheduleFixed(task, delay, period)
  }

  def cancel(): Unit = canceled = true

  def purge(): Int = 0

}


text:
package api

import "github.com/gin-gonic/gin"

// HelloHandler handles hello
func HelloHandler(c *gin.Context) {
	c.JSON(200, gin.H{
		"text": "Hello World.",
	})
}


text:
package reactor.pipe;

import org.junit.Test;
import org.pcollections.TreePVector;
import reactor.core.processor.RingBufferWorkProcessor;
import reactor.fn.Consumer;
import reactor.pipe.concurrent.AVar;
import reactor.pipe.concurrent.Atom;
import reactor.pipe.key.Key;
import reactor.pipe.registry.ConcurrentRegistry;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;

public class AnonymousPipeTest extends AbstractFirehoseTest {

  @Test
  public void testMap() throws InterruptedException {
    NamedPipe<Integer> pipe = new NamedPipe<>(firehose);
    AVar<Integer> res = new AVar<>();

    pipe.anonymous(Key.wrap("source"))
        .map((i) -> i + 1)
        .map(i -> i * 2)
        .consume(res::set);

    pipe.notify(Key.wrap("source"), 1);

    assertThat(res.get(1, TimeUnit.SECONDS), is(4));
  }

  @Test
  public void statefulMapTest() throws InterruptedException {
    AVar<Integer> res = new AVar<>(3);
    NamedPipe<Integer> intPipe = new NamedPipe<>(firehose);

    intPipe.anonymous(Key.wrap("key1"))
           .map((i) -> i + 1)
           .map((Atom<Integer> state, Integer i) -> {
                  return state.update(old -> old + i);
                },
                0)
           .consume(res::set);

    intPipe.notify(Key.wrap("key1"), 1);
    intPipe.notify(Key.wrap("key1"), 2);
    intPipe.notify(Key.wrap("key1"), 3);

    assertThat(res.get(LATCH_TIMEOUT, LATCH_TIME_UNIT), is(9));
  }

  @Test
  public void testFilter() throws InterruptedException {
    NamedPipe<Integer> pipe = new NamedPipe<>(firehose);
    AVar<Integer> res = new AVar<>();

    pipe.anonymous(Key.wrap("source"))
        .map(i -> i + 1)
        .filter(i -> i % 2 != 0)
        .map(i -> i * 2)

        .consume(res::set);

    pipe.notify(Key.wrap("source"), 1);
    pipe.notify(Key.wrap("source"), 2);

    assertThat(res.get(1, TimeUnit.SECONDS), is(6));
  }

  @Test
  public void testPartition() throws InterruptedException {
    NamedPipe<Integer> pipe = new NamedPipe<>(firehose);
    AVar<List<Integer>> res = new AVar<>();

    pipe.anonymous(Key.wrap("source"))
        .partition((i) -> {
          return i.size() == 5;
        })
        .consume(res::set);

    pipe.notify(Key.wrap("source"), 1);
    pipe.notify(Key.wrap("source"), 2);
    pipe.notify(Key.wrap("source"), 3);
    pipe.notify(Key.wrap("source"), 4);
    pipe.notify(Key.wrap("source"), 5);
    pipe.notify(Key.wrap("source"), 6);
    pipe.notify(Key.wrap("source"), 7);

    assertThat(res.get(1, TimeUnit.SECONDS), is(TreePVector.from(Arrays.asList(1, 2, 3, 4, 5))));
  }

  @Test
  public void testSlide() throws InterruptedException {
    NamedPipe<Integer> pipe = new NamedPipe<>(firehose);
    AVar<List<Integer>> res = new AVar<>(6);

    pipe.anonymous(Key.wrap("source"))
        .slide(i -> {
          return i.subList(i.size() > 5 ? i.size() - 5 : 0,
                           i.size());
        })
        .consume(res::set);

    pipe.notify(Key.wrap("source"), 1);
    pipe.notify(Key.wrap("source"), 2);
    pipe.notify(Key.wrap("source"), 3);
    pipe.notify(Key.wrap("source"), 4);
    pipe.notify(Key.wrap("source"), 5);
    pipe.notify(Key.wrap("source"), 6);

    assertThat(res.get(1, TimeUnit.SECONDS), is(TreePVector.from(Arrays.asList(2,3,4,5,6))));
  }

  @Test
  public void testNotify() throws InterruptedException {
    NamedPipe<Integer> pipe = new NamedPipe<>(firehose);
    AVar<Integer> res = new AVar<>();

    AnonymousPipe<Integer> s = pipe.anonymous(Key.wrap("source"));

    s.map((i) -> i + 1)
     .map(i -> i * 2)
     .consume(res::set);

    pipe.notify(Key.wrap("source"), 1);

    assertThat(res.get(10, TimeUnit.SECONDS), is(4));
  }

  @Test
  public void testUnregister() throws InterruptedException {
    NamedPipe<Integer> pipe = new NamedPipe<>(firehose);
    CountDownLatch latch = new CountDownLatch(1);

    AnonymousPipe<Integer> s = pipe.anonymous(Key.wrap("source"));

    s.map((i) -> i + 1)
     .map(i -> i * 2)
     .consume(i -> latch.countDown());

    pipe.notify(Key.wrap("source"), 1);
    latch.await(10, TimeUnit.SECONDS);
    s.unregister();

    assertThat(pipe.firehose().getConsumerRegistry().stream().count(), is(0L));
  }

  @Test
  public void testRedirect() throws InterruptedException {
    Key destination = Key.wrap("destination");
    NamedPipe<Integer> pipe = new NamedPipe<>(firehose);
    AVar<Integer> res = new AVar<>();

    AnonymousPipe<Integer> s = pipe.anonymous(Key.wrap("source"));

    s.map((i) -> i + 1)
     .map(i -> i * 2)
     .redirect(destination);

    pipe.consume(destination, (Integer i) -> res.set(i));

    pipe.notify(Key.wrap("source"), 1);

    assertThat(res.get(1, TimeUnit.SECONDS), is(4));
  }

  @Test
  public void testConsume() throws InterruptedException {
    NamedPipe<Integer> pipe = new NamedPipe<>(firehose);
    AVar<Integer> resValue = new AVar<>();
    AVar<Key> resKey = new AVar<>();

    AnonymousPipe<Integer> s = pipe.anonymous(Key.wrap("source"));

    s.map((i) -> i + 1)
     .map(i -> i * 2)
     .consume((k, v) -> {
       resKey.set(k);
       resValue.set(v);
     });

    pipe.notify(Key.wrap("source"), 1);

    assertThat(resKey.get(1, TimeUnit.SECONDS).getPart(0), is("source"));
    assertThat(resValue.get(1, TimeUnit.SECONDS), is(4));
  }

  @Test
  public void testSmoke() throws InterruptedException { // Tests backpressure and in-thread dispatches
    Firehose<Key> concurrentFirehose = new Firehose<>(new ConcurrentRegistry<>(),
                                                      RingBufferWorkProcessor.create(Executors.newFixedThreadPool(4),
                                                                                256),
                                                      4,
                                                      new Consumer<Throwable>() {
                                                        @Override
                                                        public void accept(Throwable throwable) {
                                                          System.out.printf("Exception caught while dispatching: %s\n",
                                                                            throwable.getMessage());
                                                          throwable.printStackTrace();
                                                        }
                                                      });

    int iterations = 2000;
    CountDownLatch latch = new CountDownLatch(iterations);

    NamedPipe<Integer> pipe = new NamedPipe<>(firehose);
    pipe.anonymous(Key.wrap("key1"))
        .map((i) -> i + 1)
        .map(i -> {
          try {
            Thread.sleep(10);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          return i * 2;
        })
        .consume((i_) -> latch.countDown());

    for (int i = 0; i < iterations; i++) {
      firehose.notify(Key.wrap("key1"), i);
      if (i % 500 == 0) {
        System.out.println("Processed " + i + " keys");
      }
    }

    latch.await(5, TimeUnit.MINUTES);
    assertThat(latch.getCount(), is(0L));

    concurrentFirehose.shutdown();
  }
}


text:
//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
//  This source code is licensed under both the GPLv2 (found in the
//  COPYING file in the root directory) and Apache 2.0 License
//  (found in the LICENSE.Apache file in the root directory).
//
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "db/db_impl/db_impl.h"

#include <cinttypes>
#include <set>
#include <unordered_set>
#include "db/event_helpers.h"
#include "db/memtable_list.h"
#include "file/file_util.h"
#include "file/filename.h"
#include "file/sst_file_manager_impl.h"
#include "util/autovector.h"

namespace ROCKSDB_NAMESPACE {

uint64_t DBImpl::MinLogNumberToKeep() {
  if (allow_2pc()) {
    return versions_->min_log_number_to_keep_2pc();
  } else {
    return versions_->MinLogNumberWithUnflushedData();
  }
}

uint64_t DBImpl::MinObsoleteSstNumberToKeep() {
  mutex_.AssertHeld();
  if (!pending_outputs_.empty()) {
    return *pending_outputs_.begin();
  }
  return std::numeric_limits<uint64_t>::max();
}

// * Returns the list of live files in 'sst_live' and 'blob_live'.
// If it's doing full scan:
// * Returns the list of all files in the filesystem in
// 'full_scan_candidate_files'.
// Otherwise, gets obsolete files from VersionSet.
// no_full_scan = true -- never do the full scan using GetChildren()
// force = false -- don't force the full scan, except every
//  mutable_db_options_.delete_obsolete_files_period_micros
// force = true -- force the full scan
void DBImpl::FindObsoleteFiles(JobContext* job_context, bool force,
                               bool no_full_scan) {
  mutex_.AssertHeld();

  // if deletion is disabled, do nothing
  if (disable_delete_obsolete_files_ > 0) {
    return;
  }

  bool doing_the_full_scan = false;

  // logic for figuring out if we're doing the full scan
  if (no_full_scan) {
    doing_the_full_scan = false;
  } else if (force ||
             mutable_db_options_.delete_obsolete_files_period_micros == 0) {
    doing_the_full_scan = true;
  } else {
    const uint64_t now_micros = env_->NowMicros();
    if ((delete_obsolete_files_last_run_ +
         mutable_db_options_.delete_obsolete_files_period_micros) <
        now_micros) {
      doing_the_full_scan = true;
      delete_obsolete_files_last_run_ = now_micros;
    }
  }

  // don't delete files that might be currently written to from compaction
  // threads
  // Since job_context->min_pending_output is set, until file scan finishes,
  // mutex_ cannot be released. Otherwise, we might see no min_pending_output
  // here but later find newer generated unfinalized files while scanning.
  job_context->min_pending_output = MinObsoleteSstNumberToKeep();

  // Get obsolete files.  This function will also update the list of
  // pending files in VersionSet().
  versions_->GetObsoleteFiles(
      &job_context->sst_delete_files, &job_context->blob_delete_files,
      &job_context->manifest_delete_files, job_context->min_pending_output);

  // Mark the elements in job_context->sst_delete_files and
  // job_context->blob_delete_files as "grabbed for purge" so that other threads
  // calling FindObsoleteFiles with full_scan=true will not add these files to
  // candidate list for purge.
  for (const auto& sst_to_del : job_context->sst_delete_files) {
    MarkAsGrabbedForPurge(sst_to_del.metadata->fd.GetNumber());
  }

  for (const auto& blob_file : job_context->blob_delete_files) {
    MarkAsGrabbedForPurge(blob_file.GetBlobFileNumber());
  }

  // store the current filenum, lognum, etc
  job_context->manifest_file_number = versions_->manifest_file_number();
  job_context->pending_manifest_file_number =
      versions_->pending_manifest_file_number();
  job_context->log_number = MinLogNumberToKeep();
  job_context->prev_log_number = versions_->prev_log_number();

  versions_->AddLiveFiles(&job_context->sst_live, &job_context->blob_live);
  if (doing_the_full_scan) {
    InfoLogPrefix info_log_prefix(!immutable_db_options_.db_log_dir.empty(),
                                  dbname_);
    std::set<std::string> paths;
    for (size_t path_id = 0; path_id < immutable_db_options_.db_paths.size();
         path_id++) {
      paths.insert(immutable_db_options_.db_paths[path_id].path);
    }

    // Note that if cf_paths is not specified in the ColumnFamilyOptions
    // of a particular column family, we use db_paths as the cf_paths
    // setting. Hence, there can be multiple duplicates of files from db_paths
    // in the following code. The duplicate are removed while identifying
    // unique files in PurgeObsoleteFiles.
    for (auto cfd : *versions_->GetColumnFamilySet()) {
      for (size_t path_id = 0; path_id < cfd->ioptions()->cf_paths.size();
           path_id++) {
        auto& path = cfd->ioptions()->cf_paths[path_id].path;

        if (paths.find(path) == paths.end()) {
          paths.insert(path);
        }
      }
    }

    for (auto& path : paths) {
      // set of all files in the directory. We'll exclude files that are still
      // alive in the subsequent processings.
      std::vector<std::string> files;
      env_->GetChildren(path, &files);  // Ignore errors
      for (const std::string& file : files) {
        uint64_t number;
        FileType type;
        // 1. If we cannot parse the file name, we skip;
        // 2. If the file with file_number equals number has already been
        // grabbed for purge by another compaction job, or it has already been
        // schedule for purge, we also skip it if we
        // are doing full scan in order to avoid double deletion of the same
        // file under race conditions. See
        // https://github.com/facebook/rocksdb/issues/3573
        if (!ParseFileName(file, &number, info_log_prefix.prefix, &type) ||
            !ShouldPurge(number)) {
          continue;
        }

        // TODO(icanadi) clean up this mess to avoid having one-off "/" prefixes
        job_context->full_scan_candidate_files.emplace_back("/" + file, path);
      }
    }

    // Add log files in wal_dir
    if (immutable_db_options_.wal_dir != dbname_) {
      std::vector<std::string> log_files;
      env_->GetChildren(immutable_db_options_.wal_dir,
                        &log_files);  // Ignore errors
      for (const std::string& log_file : log_files) {
        job_context->full_scan_candidate_files.emplace_back(
            log_file, immutable_db_options_.wal_dir);
      }
    }
    // Add info log files in db_log_dir
    if (!immutable_db_options_.db_log_dir.empty() &&
        immutable_db_options_.db_log_dir != dbname_) {
      std::vector<std::string> info_log_files;
      // Ignore errors
      env_->GetChildren(immutable_db_options_.db_log_dir, &info_log_files);
      for (std::string& log_file : info_log_files) {
        job_context->full_scan_candidate_files.emplace_back(
            log_file, immutable_db_options_.db_log_dir);
      }
    }
  }

  // logs_ is empty when called during recovery, in which case there can't yet
  // be any tracked obsolete logs
  if (!alive_log_files_.empty() && !logs_.empty()) {
    uint64_t min_log_number = job_context->log_number;
    size_t num_alive_log_files = alive_log_files_.size();
    // find newly obsoleted log files
    while (alive_log_files_.begin()->number < min_log_number) {
      auto& earliest = *alive_log_files_.begin();
      if (immutable_db_options_.recycle_log_file_num >
          log_recycle_files_.size()) {
        ROCKS_LOG_INFO(immutable_db_options_.info_log,
                       "adding log %" PRIu64 " to recycle list\n",
                       earliest.number);
        log_recycle_files_.push_back(earliest.number);
      } else {
        job_context->log_delete_files.push_back(earliest.number);
      }
      if (job_context->size_log_to_delete == 0) {
        job_context->prev_total_log_size = total_log_size_;
        job_context->num_alive_log_files = num_alive_log_files;
      }
      job_context->size_log_to_delete += earliest.size;
      total_log_size_ -= earliest.size;
      if (two_write_queues_) {
        log_write_mutex_.Lock();
      }
      alive_log_files_.pop_front();
      if (two_write_queues_) {
        log_write_mutex_.Unlock();
      }
      // Current log should always stay alive since it can't have
      // number < MinLogNumber().
      assert(alive_log_files_.size());
    }
    while (!logs_.empty() && logs_.front().number < min_log_number) {
      auto& log = logs_.front();
      if (log.getting_synced) {
        log_sync_cv_.Wait();
        // logs_ could have changed while we were waiting.
        continue;
      }
      logs_to_free_.push_back(log.ReleaseWriter());
      {
        InstrumentedMutexLock wl(&log_write_mutex_);
        logs_.pop_front();
      }
    }
    // Current log cannot be obsolete.
    assert(!logs_.empty());
  }

  // We're just cleaning up for DB::Write().
  assert(job_context->logs_to_free.empty());
  job_context->logs_to_free = logs_to_free_;
  job_context->log_recycle_files.assign(log_recycle_files_.begin(),
                                        log_recycle_files_.end());
  if (job_context->HaveSomethingToDelete()) {
    ++pending_purge_obsolete_files_;
  }
  logs_to_free_.clear();
}

namespace {
bool CompareCandidateFile(const JobContext::CandidateFileInfo& first,
                          const JobContext::CandidateFileInfo& second) {
  if (first.file_name > second.file_name) {
    return true;
  } else if (first.file_name < second.file_name) {
    return false;
  } else {
    return (first.file_path > second.file_path);
  }
}
};  // namespace

// Delete obsolete files and log status and information of file deletion
void DBImpl::DeleteObsoleteFileImpl(int job_id, const std::string& fname,
                                    const std::string& path_to_sync,
                                    FileType type, uint64_t number) {
  TEST_SYNC_POINT_CALLBACK("DBImpl::DeleteObsoleteFileImpl::BeforeDeletion",
                           const_cast<std::string*>(&fname));

  Status file_deletion_status;
  if (type == kTableFile || type == kBlobFile || type == kLogFile) {
    file_deletion_status =
        DeleteDBFile(&immutable_db_options_, fname, path_to_sync,
                     /*force_bg=*/false, /*force_fg=*/!wal_in_db_path_);
  } else {
    file_deletion_status = env_->DeleteFile(fname);
  }
  TEST_SYNC_POINT_CALLBACK("DBImpl::DeleteObsoleteFileImpl:AfterDeletion",
                           &file_deletion_status);
  if (file_deletion_status.ok()) {
    ROCKS_LOG_DEBUG(immutable_db_options_.info_log,
                    "[JOB %d] Delete %s type=%d #%" PRIu64 " -- %s\n", job_id,
                    fname.c_str(), type, number,
                    file_deletion_status.ToString().c_str());
  } else if (env_->FileExists(fname).IsNotFound()) {
    ROCKS_LOG_INFO(
        immutable_db_options_.info_log,
        "[JOB %d] Tried to delete a non-existing file %s type=%d #%" PRIu64
        " -- %s\n",
        job_id, fname.c_str(), type, number,
        file_deletion_status.ToString().c_str());
  } else {
    ROCKS_LOG_ERROR(immutable_db_options_.info_log,
                    "[JOB %d] Failed to delete %s type=%d #%" PRIu64 " -- %s\n",
                    job_id, fname.c_str(), type, number,
                    file_deletion_status.ToString().c_str());
  }
  if (type == kTableFile) {
    EventHelpers::LogAndNotifyTableFileDeletion(
        &event_logger_, job_id, number, fname, file_deletion_status, GetName(),
        immutable_db_options_.listeners);
  }
}

// Diffs the files listed in filenames and those that do not
// belong to live files are possibly removed. Also, removes all the
// files in sst_delete_files and log_delete_files.
// It is not necessary to hold the mutex when invoking this method.
void DBImpl::PurgeObsoleteFiles(JobContext& state, bool schedule_only) {
  TEST_SYNC_POINT("DBImpl::PurgeObsoleteFiles:Begin");
  // we'd better have sth to delete
  assert(state.HaveSomethingToDelete());

  // FindObsoleteFiles() should've populated this so nonzero
  assert(state.manifest_file_number != 0);

  // Now, convert lists to unordered sets, WITHOUT mutex held; set is slow.
  std::unordered_set<uint64_t> sst_live_set(state.sst_live.begin(),
                                            state.sst_live.end());
  std::unordered_set<uint64_t> blob_live_set(state.blob_live.begin(),
                                             state.blob_live.end());
  std::unordered_set<uint64_t> log_recycle_files_set(
      state.log_recycle_files.begin(), state.log_recycle_files.end());

  auto candidate_files = state.full_scan_candidate_files;
  candidate_files.reserve(
      candidate_files.size() + state.sst_delete_files.size() +
      state.blob_delete_files.size() + state.log_delete_files.size() +
      state.manifest_delete_files.size());
  // We may ignore the dbname when generating the file names.
  for (auto& file : state.sst_delete_files) {
    candidate_files.emplace_back(
        MakeTableFileName(file.metadata->fd.GetNumber()), file.path);
    if (file.metadata->table_reader_handle) {
      table_cache_->Release(file.metadata->table_reader_handle);
    }
    file.DeleteMetadata();
  }

  for (const auto& blob_file : state.blob_delete_files) {
    candidate_files.emplace_back(BlobFileName(blob_file.GetBlobFileNumber()),
                                 blob_file.GetPath());
  }

  for (auto file_num : state.log_delete_files) {
    if (file_num > 0) {
      candidate_files.emplace_back(LogFileName(file_num),
                                   immutable_db_options_.wal_dir);
    }
  }
  for (const auto& filename : state.manifest_delete_files) {
    candidate_files.emplace_back(filename, dbname_);
  }

  // dedup state.candidate_files so we don't try to delete the same
  // file twice
  std::sort(candidate_files.begin(), candidate_files.end(),
            CompareCandidateFile);
  candidate_files.erase(
      std::unique(candidate_files.begin(), candidate_files.end()),
      candidate_files.end());

  if (state.prev_total_log_size > 0) {
    ROCKS_LOG_INFO(immutable_db_options_.info_log,
                   "[JOB %d] Try to delete WAL files size %" PRIu64
                   ", prev total WAL file size %" PRIu64
                   ", number of live WAL files %" ROCKSDB_PRIszt ".\n",
                   state.job_id, state.size_log_to_delete,
                   state.prev_total_log_size, state.num_alive_log_files);
  }

  std::vector<std::string> old_info_log_files;
  InfoLogPrefix info_log_prefix(!immutable_db_options_.db_log_dir.empty(),
                                dbname_);

  // File numbers of most recent two OPTIONS file in candidate_files (found in
  // previos FindObsoleteFiles(full_scan=true))
  // At this point, there must not be any duplicate file numbers in
  // candidate_files.
  uint64_t optsfile_num1 = std::numeric_limits<uint64_t>::min();
  uint64_t optsfile_num2 = std::numeric_limits<uint64_t>::min();
  for (const auto& candidate_file : candidate_files) {
    const std::string& fname = candidate_file.file_name;
    uint64_t number;
    FileType type;
    if (!ParseFileName(fname, &number, info_log_prefix.prefix, &type) ||
        type != kOptionsFile) {
      continue;
    }
    if (number > optsfile_num1) {
      optsfile_num2 = optsfile_num1;
      optsfile_num1 = number;
    } else if (number > optsfile_num2) {
      optsfile_num2 = number;
    }
  }

  // Close WALs before trying to delete them.
  for (const auto w : state.logs_to_free) {
    // TODO: maybe check the return value of Close.
    w->Close();
  }

  bool own_files = OwnTablesAndLogs();
  std::unordered_set<uint64_t> files_to_del;
  for (const auto& candidate_file : candidate_files) {
    const std::string& to_delete = candidate_file.file_name;
    uint64_t number;
    FileType type;
    // Ignore file if we cannot recognize it.
    if (!ParseFileName(to_delete, &number, info_log_prefix.prefix, &type)) {
      continue;
    }

    bool keep = true;
    switch (type) {
      case kLogFile:
        keep = ((number >= state.log_number) ||
                (number == state.prev_log_number) ||
                (log_recycle_files_set.find(number) !=
                 log_recycle_files_set.end()));
        break;
      case kDescriptorFile:
        // Keep my manifest file, and any newer incarnations'
        // (can happen during manifest roll)
        keep = (number >= state.manifest_file_number);
        break;
      case kTableFile:
        // If the second condition is not there, this makes
        // DontDeletePendingOutputs fail
        keep = (sst_live_set.find(number) != sst_live_set.end()) ||
               number >= state.min_pending_output;
        if (!keep) {
          files_to_del.insert(number);
        }
        break;
      case kBlobFile:
        keep = number >= state.min_pending_output ||
               (blob_live_set.find(number) != blob_live_set.end());
        if (!keep) {
          files_to_del.insert(number);
        }
        break;
      case kTempFile:
        // Any temp files that are currently being written to must
        // be recorded in pending_outputs_, which is inserted into "live".
        // Also, SetCurrentFile creates a temp file when writing out new
        // manifest, which is equal to state.pending_manifest_file_number. We
        // should not delete that file
        //
        // TODO(yhchiang): carefully modify the third condition to safely
        //                 remove the temp options files.
        keep = (sst_live_set.find(number) != sst_live_set.end()) ||
               (blob_live_set.find(number) != blob_live_set.end()) ||
               (number == state.pending_manifest_file_number) ||
               (to_delete.find(kOptionsFileNamePrefix) != std::string::npos);
        break;
      case kInfoLogFile:
        keep = true;
        if (number != 0) {
          old_info_log_files.push_back(to_delete);
        }
        break;
      case kOptionsFile:
        keep = (number >= optsfile_num2);
        TEST_SYNC_POINT_CALLBACK(
            "DBImpl::PurgeObsoleteFiles:CheckOptionsFiles:1",
            reinterpret_cast<void*>(&number));
        TEST_SYNC_POINT_CALLBACK(
            "DBImpl::PurgeObsoleteFiles:CheckOptionsFiles:2",
            reinterpret_cast<void*>(&keep));
        break;
      case kCurrentFile:
      case kDBLockFile:
      case kIdentityFile:
      case kMetaDatabase:
        keep = true;
        break;
    }

    if (keep) {
      continue;
    }

    std::string fname;
    std::string dir_to_sync;
    if (type == kTableFile) {
      // evict from cache
      TableCache::Evict(table_cache_.get(), number);
      fname = MakeTableFileName(candidate_file.file_path, number);
      dir_to_sync = candidate_file.file_path;
    } else if (type == kBlobFile) {
      fname = BlobFileName(candidate_file.file_path, number);
      dir_to_sync = candidate_file.file_path;
    } else {
      dir_to_sync =
          (type == kLogFile) ? immutable_db_options_.wal_dir : dbname_;
      fname = dir_to_sync +
              ((!dir_to_sync.empty() && dir_to_sync.back() == '/') ||
                       (!to_delete.empty() && to_delete.front() == '/')
                   ? ""
                   : "/") +
              to_delete;
    }

#ifndef ROCKSDB_LITE
    if (type == kLogFile && (immutable_db_options_.wal_ttl_seconds > 0 ||
                             immutable_db_options_.wal_size_limit_mb > 0)) {
      wal_manager_.ArchiveWALFile(fname, number);
      continue;
    }
#endif  // !ROCKSDB_LITE

    // If I do not own these files, e.g. secondary instance with max_open_files
    // = -1, then no need to delete or schedule delete these files since they
    // will be removed by their owner, e.g. the primary instance.
    if (!own_files) {
      continue;
    }
    Status file_deletion_status;
    if (schedule_only) {
      InstrumentedMutexLock guard_lock(&mutex_);
      SchedulePendingPurge(fname, dir_to_sync, type, number, state.job_id);
    } else {
      DeleteObsoleteFileImpl(state.job_id, fname, dir_to_sync, type, number);
    }
  }

  {
    // After purging obsolete files, remove them from files_grabbed_for_purge_.
    InstrumentedMutexLock guard_lock(&mutex_);
    autovector<uint64_t> to_be_removed;
    for (auto fn : files_grabbed_for_purge_) {
      if (files_to_del.count(fn) != 0) {
        to_be_removed.emplace_back(fn);
      }
    }
    for (auto fn : to_be_removed) {
      files_grabbed_for_purge_.erase(fn);
    }
  }

  // Delete old info log files.
  size_t old_info_log_file_count = old_info_log_files.size();
  if (old_info_log_file_count != 0 &&
      old_info_log_file_count >= immutable_db_options_.keep_log_file_num) {
    std::sort(old_info_log_files.begin(), old_info_log_files.end());
    size_t end =
        old_info_log_file_count - immutable_db_options_.keep_log_file_num;
    for (unsigned int i = 0; i <= end; i++) {
      std::string& to_delete = old_info_log_files.at(i);
      std::string full_path_to_delete =
          (immutable_db_options_.db_log_dir.empty()
               ? dbname_
               : immutable_db_options_.db_log_dir) +
          "/" + to_delete;
      ROCKS_LOG_INFO(immutable_db_options_.info_log,
                     "[JOB %d] Delete info log file %s\n", state.job_id,
                     full_path_to_delete.c_str());
      Status s = env_->DeleteFile(full_path_to_delete);
      if (!s.ok()) {
        if (env_->FileExists(full_path_to_delete).IsNotFound()) {
          ROCKS_LOG_INFO(
              immutable_db_options_.info_log,
              "[JOB %d] Tried to delete non-existing info log file %s FAILED "
              "-- %s\n",
              state.job_id, to_delete.c_str(), s.ToString().c_str());
        } else {
          ROCKS_LOG_ERROR(immutable_db_options_.info_log,
                          "[JOB %d] Delete info log file %s FAILED -- %s\n",
                          state.job_id, to_delete.c_str(),
                          s.ToString().c_str());
        }
      }
    }
  }
#ifndef ROCKSDB_LITE
  wal_manager_.PurgeObsoleteWALFiles();
#endif  // ROCKSDB_LITE
  LogFlush(immutable_db_options_.info_log);
  InstrumentedMutexLock l(&mutex_);
  --pending_purge_obsolete_files_;
  assert(pending_purge_obsolete_files_ >= 0);
  if (pending_purge_obsolete_files_ == 0) {
    bg_cv_.SignalAll();
  }
  TEST_SYNC_POINT("DBImpl::PurgeObsoleteFiles:End");
}

void DBImpl::DeleteObsoleteFiles() {
  mutex_.AssertHeld();
  JobContext job_context(next_job_id_.fetch_add(1));
  FindObsoleteFiles(&job_context, true);

  mutex_.Unlock();
  if (job_context.HaveSomethingToDelete()) {
    PurgeObsoleteFiles(job_context);
  }
  job_context.Clean();
  mutex_.Lock();
}

uint64_t FindMinPrepLogReferencedByMemTable(
    VersionSet* vset, const ColumnFamilyData* cfd_to_flush,
    const autovector<MemTable*>& memtables_to_flush) {
  uint64_t min_log = 0;

  // we must look through the memtables for two phase transactions
  // that have been committed but not yet flushed
  for (auto loop_cfd : *vset->GetColumnFamilySet()) {
    if (loop_cfd->IsDropped() || loop_cfd == cfd_to_flush) {
      continue;
    }

    auto log = loop_cfd->imm()->PrecomputeMinLogContainingPrepSection(
        memtables_to_flush);

    if (log > 0 && (min_log == 0 || log < min_log)) {
      min_log = log;
    }

    log = loop_cfd->mem()->GetMinLogContainingPrepSection();

    if (log > 0 && (min_log == 0 || log < min_log)) {
      min_log = log;
    }
  }

  return min_log;
}

uint64_t PrecomputeMinLogNumberToKeep(
    VersionSet* vset, const ColumnFamilyData& cfd_to_flush,
    autovector<VersionEdit*> edit_list,
    const autovector<MemTable*>& memtables_to_flush,
    LogsWithPrepTracker* prep_tracker) {
  assert(vset != nullptr);
  assert(prep_tracker != nullptr);
  // Calculate updated min_log_number_to_keep
  // Since the function should only be called in 2pc mode, log number in
  // the version edit should be sufficient.

  // Precompute the min log number containing unflushed data for the column
  // family being flushed (`cfd_to_flush`).
  uint64_t cf_min_log_number_to_keep = 0;
  for (auto& e : edit_list) {
    if (e->HasLogNumber()) {
      cf_min_log_number_to_keep =
          std::max(cf_min_log_number_to_keep, e->GetLogNumber());
    }
  }
  if (cf_min_log_number_to_keep == 0) {
    // No version edit contains information on log number. The log number
    // for this column family should stay the same as it is.
    cf_min_log_number_to_keep = cfd_to_flush.GetLogNumber();
  }

  // Get min log number containing unflushed data for other column families.
  uint64_t min_log_number_to_keep =
      vset->PreComputeMinLogNumberWithUnflushedData(&cfd_to_flush);
  if (cf_min_log_number_to_keep != 0) {
    min_log_number_to_keep =
        std::min(cf_min_log_number_to_keep, min_log_number_to_keep);
  }

  // if are 2pc we must consider logs containing prepared
  // sections of outstanding transactions.
  //
  // We must check min logs with outstanding prep before we check
  // logs references by memtables because a log referenced by the
  // first data structure could transition to the second under us.
  //
  // TODO: iterating over all column families under db mutex.
  // should find more optimal solution
  auto min_log_in_prep_heap =
      prep_tracker->FindMinLogContainingOutstandingPrep();

  if (min_log_in_prep_heap != 0 &&
      min_log_in_prep_heap < min_log_number_to_keep) {
    min_log_number_to_keep = min_log_in_prep_heap;
  }

  uint64_t min_log_refed_by_mem = FindMinPrepLogReferencedByMemTable(
      vset, &cfd_to_flush, memtables_to_flush);

  if (min_log_refed_by_mem != 0 &&
      min_log_refed_by_mem < min_log_number_to_keep) {
    min_log_number_to_keep = min_log_refed_by_mem;
  }
  return min_log_number_to_keep;
}

Status DBImpl::FinishBestEffortsRecovery() {
  mutex_.AssertHeld();
  std::vector<std::string> paths;
  paths.push_back(NormalizePath(dbname_ + std::string(1, kFilePathSeparator)));
  for (const auto& db_path : immutable_db_options_.db_paths) {
    paths.push_back(
        NormalizePath(db_path.path + std::string(1, kFilePathSeparator)));
  }
  for (const auto* cfd : *versions_->GetColumnFamilySet()) {
    for (const auto& cf_path : cfd->ioptions()->cf_paths) {
      paths.push_back(
          NormalizePath(cf_path.path + std::string(1, kFilePathSeparator)));
    }
  }
  // Dedup paths
  std::sort(paths.begin(), paths.end());
  paths.erase(std::unique(paths.begin(), paths.end()), paths.end());

  uint64_t next_file_number = versions_->current_next_file_number();
  uint64_t largest_file_number = next_file_number;
  std::set<std::string> files_to_delete;
  for (const auto& path : paths) {
    std::vector<std::string> files;
    env_->GetChildren(path, &files);
    for (const auto& fname : files) {
      uint64_t number = 0;
      FileType type;
      if (!ParseFileName(fname, &number, &type)) {
        continue;
      }
      // path ends with '/' or '\\'
      const std::string normalized_fpath = path + fname;
      largest_file_number = std::max(largest_file_number, number);
      if (type == kTableFile && number >= next_file_number &&
          files_to_delete.find(normalized_fpath) == files_to_delete.end()) {
        files_to_delete.insert(normalized_fpath);
      }
    }
  }
  if (largest_file_number > next_file_number) {
    versions_->next_file_number_.store(largest_file_number + 1);
  }

  VersionEdit edit;
  edit.SetNextFile(versions_->next_file_number_.load());
  assert(versions_->GetColumnFamilySet());
  ColumnFamilyData* default_cfd = versions_->GetColumnFamilySet()->GetDefault();
  assert(default_cfd);
  // Even if new_descriptor_log is false, we will still switch to a new
  // MANIFEST and update CURRENT file, since this is in recovery.
  Status s = versions_->LogAndApply(
      default_cfd, *default_cfd->GetLatestMutableCFOptions(), &edit, &mutex_,
      directories_.GetDbDir(), /*new_descriptor_log*/ false);
  if (!s.ok()) {
    return s;
  }

  mutex_.Unlock();
  for (const auto& fname : files_to_delete) {
    s = env_->DeleteFile(fname);
    if (!s.ok()) {
      break;
    }
  }
  mutex_.Lock();
  return s;
}

}  // namespace ROCKSDB_NAMESPACE


text:
<bill session="110" type="h" number="1230" updated="2009-01-08T19:24:37-05:00">
	<status><introduced date="1172638800" datetime="2007-02-28"/></status>

	<introduced date="1172638800" datetime="2007-02-28"/>
	<titles>
		<title type="short" as="introduced">Puerto Rico Self-Determination Act of 2007</title>
		<title type="official" as="introduced">To recognize the right of the People of Puerto Rico to call a Constitutional Convention through which the people would exercise their natural right to self-determination, and to establish a mechanism for congressional consideration of such decision.</title>
	</titles>
	<sponsor id="400416"/>
	<cosponsors>
		<cosponsor id="400128" joined="2007-02-28"/>
		<cosponsor id="400073" joined="2007-02-28"/>
		<cosponsor id="400199" joined="2007-02-28"/>
		<cosponsor id="400227" joined="2007-06-07"/>
		<cosponsor id="400364" joined="2007-05-08"/>
		<cosponsor id="400257" joined="2007-04-19"/>
		<cosponsor id="400413" joined="2007-02-28"/>
		<cosponsor id="400160" joined="2007-07-26"/>
		<cosponsor id="400263" joined="2007-06-26"/>
		<cosponsor id="400080" joined="2007-02-28"/>
		<cosponsor id="412221" joined="2007-03-09"/>
		<cosponsor id="400209" joined="2007-04-19"/>
		<cosponsor id="400242" joined="2007-04-19"/>
		<cosponsor id="400333" joined="2007-02-28"/>
		<cosponsor id="400271" joined="2007-02-28"/>
		<cosponsor id="400170" joined="2007-03-09"/>
		<cosponsor id="400065" joined="2007-04-19"/>
		<cosponsor id="400198" joined="2007-05-10"/>
		<cosponsor id="400116" joined="2007-02-28"/>
		<cosponsor id="400084" joined="2007-05-14"/>
		<cosponsor id="400409" joined="2007-03-09"/>
		<cosponsor id="400384" joined="2007-02-28"/>
		<cosponsor id="400130" joined="2007-02-28"/>
		<cosponsor id="400030" joined="2007-02-28"/>
		<cosponsor id="400339" joined="2007-03-09"/>
		<cosponsor id="400082" joined="2007-02-28"/>
		<cosponsor id="400275" joined="2007-03-09"/>
		<cosponsor id="400432" joined="2007-02-28"/>
		<cosponsor id="412235" joined="2007-08-02"/>
		<cosponsor id="400346" joined="2007-03-09"/>
		<cosponsor id="400140" joined="2007-04-19"/>
		<cosponsor id="400422" joined="2007-03-09"/>
		<cosponsor id="400195" joined="2007-06-15"/>
		<cosponsor id="400378" joined="2007-04-19"/>
		<cosponsor id="400350" joined="2007-06-05"/>
		<cosponsor id="400360" joined="2007-05-14"/>
		<cosponsor id="400299" joined="2007-02-28"/>
		<cosponsor id="400074" joined="2007-06-25"/>
		<cosponsor id="412186" joined="2007-02-28"/>
		<cosponsor id="400093" joined="2007-05-08"/>
		<cosponsor id="400291" joined="2007-05-08"/>
		<cosponsor id="400201" joined="2007-04-19"/>
		<cosponsor id="400185" joined="2007-02-28"/>
		<cosponsor id="400208" joined="2007-04-19"/>
		<cosponsor id="400240" joined="2007-04-19"/>
		<cosponsor id="400163" joined="2007-02-28"/>
		<cosponsor id="400100" joined="2007-02-28"/>
		<cosponsor id="400067" joined="2007-05-17"/>
	</cosponsors>
	<actions>
		<action date="1172638800" datetime="2007-02-28"><text>Referred to the House Committee on Natural Resources.</text></action>
		<action date="1173070800" datetime="2007-03-05"><text>Referred to the Subcommittee on Insular Affairs.</text></action>
		<action date="1174536000" datetime="2007-03-22"><text>Subcommittee Hearings Held.</text></action>
		<action date="1177473600" datetime="2007-04-25"><text>Subcommittee Hearings Held.</text></action>
	</actions>
	<committees>

	</committees>
	<relatedbills>

	</relatedbills>
	<subjects>

	</subjects>
	<amendments>

	</amendments>

	2/28/2007--Introduced.
Puerto Rico Self-Determination Act of 2007 - Recognizes the inherent authority of the People of Puerto Rico to call a Constitutional Convention for the purpose of proposing a Self-Determination Option for a new or modified commonwealth status, statehood, or independence. Requires such proposal, if approved by the people of Puerto Rico in a referendum, to be presented to Congress, which shall enact a joint resolution approving it and providing for its implementation. Requires a proposal that is changed or amended by Congress to be submitted to the people of Puerto Rico for approval in a referendum before it shall become effective.
Authorizes the Constitutional Convention: (1) if a self-determination proposal is rejected by Congress or by the people of Puerto Rico, to reconvene for the purpose of deliberating to adopt another proposal; and (2) to remain in session until a proposal is enacted.

</bill>


text:
{-# LANGUAGE TemplateHaskell       #-}
{-# LANGUAGE DuplicateRecordFields #-}
module Language.LSP.Types.DocumentColor where

import Data.Aeson.TH
import Data.Text (Text)
import Language.LSP.Types.Common
import Language.LSP.Types.Location
import Language.LSP.Types.Progress
import Language.LSP.Types.StaticRegistrationOptions
import Language.LSP.Types.TextDocument
import Language.LSP.Types.Utils
import Language.LSP.Types.WorkspaceEdit

data DocumentColorClientCapabilities =
  DocumentColorClientCapabilities
  { -- | Whether document color supports dynamic registration.
    _dynamicRegistration :: Maybe Bool
  } deriving (Read, Show, Eq)
deriveJSON lspOptions ''DocumentColorClientCapabilities

-- -------------------------------------

makeExtendingDatatype "DocumentColorOptions" [''WorkDoneProgressOptions] []
deriveJSON lspOptions ''DocumentColorOptions

makeExtendingDatatype "DocumentColorRegistrationOptions"
  [ ''TextDocumentRegistrationOptions
  , ''StaticRegistrationOptions
  , ''DocumentColorOptions
  ] []
deriveJSON lspOptions ''DocumentColorRegistrationOptions

-- -------------------------------------

makeExtendingDatatype "DocumentColorParams"
  [ ''WorkDoneProgressParams
  , ''PartialResultParams
  ]
  [("_textDocument", [t| TextDocumentIdentifier |])]
deriveJSON lspOptions ''DocumentColorParams

-- -------------------------------------

-- | Represents a color in RGBA space.
data Color =
  Color
    { _red   :: Int -- ^ The red component of this color in the range [0-1].
    , _green :: Int -- ^ The green component of this color in the range [0-1].
    , _blue  :: Int -- ^ The blue component of this color in the range [0-1].
    , _alpha :: Int -- ^ The alpha component of this color in the range [0-1].
    } deriving (Read, Show, Eq)
deriveJSON lspOptions ''Color

data ColorInformation =
  ColorInformation
    { _range :: Range -- ^ The range in the document where this color appears.
    , _color :: Color -- ^ The actual color value for this color range.
    } deriving (Read, Show, Eq)
deriveJSON lspOptions ''ColorInformation

-- -------------------------------------

makeExtendingDatatype "ColorPresentationParams"
  [ ''WorkDoneProgressParams
  , ''PartialResultParams
  ]
  [ ("_textDocument", [t| TextDocumentIdentifier |])
  , ("_color", [t| Color |])
  , ("_range", [t| Range |])
  ]
deriveJSON lspOptions ''ColorPresentationParams

-- -------------------------------------

data ColorPresentation =
  ColorPresentation
    { -- | The label of this color presentation. It will be shown on the color
      -- picker header. By default this is also the text that is inserted when selecting
      -- this color presentation.
      _label               :: Text
      -- | A 'TextEdit' which is applied to a document when selecting
      -- this presentation for the color.  When `falsy` the '_label'
      -- is used.
    , _textEdit            :: Maybe TextEdit
      -- | An optional array of additional 'TextEdit's that are applied when
      -- selecting this color presentation. Edits must not overlap with the main
      -- '_textEdit' nor with themselves.
    , _additionalTextEdits :: Maybe (List TextEdit)
    } deriving (Read, Show, Eq)
deriveJSON lspOptions ''ColorPresentation


text:
def maximum_value(x, y, z):
    """Finds the maximum value of three integers"""

    maximum = x

    if y > maximum:
        maximum = y
    if z > maximum:
        maximum = z

    return maximum

def main():
    """Main"""

    a = int(raw_input("Enter first integer: "))
    b = int(raw_input("Enter second integer: "))
    c = int(raw_input("Enter third integer: "))

    print "Maximum integer is", maximum_value(a, b, c)
    print

    d = float(raw_input("Enter first float: "))
    e = float(raw_input("Enter second float: "))
    f = float(raw_input("Enter third float: "))

    print "Maximum float is", maximum_value(d, e, f)
    print

    g = raw_input("Enter first string: ")
    h = raw_input("Enter second string: ")
    i = raw_input("Enter third string: ")

    print "Maximum string is", maximum_value(g, h, i)
    print

if __name__ == "__main__":
    main()


text:
goog.module('goog.ui.DrilldownRowTest');
goog.setTestOnly();

const DrilldownRow = goog.require('goog.ui.DrilldownRow');
const SafeHtml = goog.require('goog.html.SafeHtml');
const TagName = goog.require('goog.dom.TagName');
const dom = goog.require('goog.dom');
const testSuite = goog.require('goog.testing.testSuite');

function createHtmlForRow(rowText) {
  return SafeHtml.create(
      TagName.TR, {},
      SafeHtml.concat(
          SafeHtml.create(TagName.TD, {}, rowText),
          SafeHtml.create(TagName.TD, {}, 'Second column')));
}
testSuite({
  testMakeRows() {
    const ff = dom.getElement('firstRow');
    const d = new DrilldownRow({});
    const d1 = new DrilldownRow({html: createHtmlForRow('Second row')});
    const d2 = new DrilldownRow({html: createHtmlForRow('Third row')});
    const d21 = new DrilldownRow({html: createHtmlForRow('Fourth row')});
    /** @suppress {checkTypes} suppression added to enable type checking */
    const d22 = new DrilldownRow(DrilldownRow.sampleProperties);
    d.decorate(ff);
    d.addChild(d1, true);
    d.addChild(d2, true);
    d2.addChild(d21, true);
    d2.addChild(d22, true);

    assertThrows(() => {
      d.findIndex();
    });

    assertEquals(0, d1.findIndex());
    assertEquals(1, d2.findIndex());
  },
});


text:
SYNONYM

#### According to
Index Fungorum

#### Published in
Anal. Mus. nac. Hist. nat. B. Aires 6: 135 (1899)

#### Original name
Ramularia chenopodii Speg.

### Remarks
null


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<title>Code Igniter User Guide</title>

<link rel='stylesheet' type='text/css' media='all' href='../docs.css' />

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv='expires' content='-1' />
<meta http-equiv= 'pragma' content='no-cache' />
<meta name='robots' content='all' />
<meta name='author' content='Rick Ellis' />
<meta name='description' content='Code Igniter User Guide' />

Code Igniter User Guide Version Beta 1.1

Code Igniter Home  ›
User Guide Home  ›
Appflow

Full Table of Contents

Application Flow Chart

The following graphic illustrates how data flows throughout the system:

The index.php serves as the front controller which initializes the base resources needed to run Code Igniter.

Security.  Before anything of note takes place, the HTTP request is filtered for security.

The Router examines the HTTP request to determine which application controller should be used.

The Controller loads the core libraries, plugins, and helpers needed to process the specific request.

The finalized View (web page) is rendered then sent to the web browser to be seen.

Previous Topic:  Code Igniter Features
   ·
Top of Page   ·
User Guide Home   ·
Next Topic:  Model-View-Controller

Code Igniter  ·  Copyright © 2006  ·  pMachine, Inc.


text:
/**
 *
 */
package gov.va.med.imaging.exchange.business;

import gov.va.med.GlobalArtifactIdentifier;
import gov.va.med.MockDataGenerationField;
import gov.va.med.PatientIdentifier;
import gov.va.med.PatientIdentifierType;
import gov.va.med.StudyURNFactory;
import gov.va.med.imaging.BhieStudyURN;
import gov.va.med.imaging.StudyURN;
import gov.va.med.imaging.exceptions.URNFormatException;
import gov.va.med.imaging.exchange.enums.ObjectOrigin;
import gov.va.med.imaging.exchange.enums.StudyDeletedImageState;
import gov.va.med.imaging.exchange.enums.StudyLoadLevel;
import gov.va.med.imaging.exchange.enums.ObjectStatus;

import java.io.Serializable;
import java.util.*;

import org.apache.log4j.Logger;

/**
 * @author vhaiswwerfej
 *
 */
public class Study
implements Serializable, Comparable<Study>, Iterable<Series>, StudyFilterFilterable
{
	private static final long serialVersionUID = -7467740571635450273L;
	private final static Logger logger = Logger.getLogger(Study.class);

	private final GlobalArtifactIdentifier globalArtifactIdentifier;
	// JMW 9/30/2010 P104 - study load level is no longer final to support updating a study to
	// include more information (usually the report although potentially the images)
	// the StudyLoadLevel should only be changed by specific methods that set other values
	// ie: only update the StudyLoadLevel if the report or images are added to the Study object
	private StudyLoadLevel studyLoadLevel;
	private final StudyDeletedImageState studyDeletedImageState;

	private Hashtable<String, String> studyValues = new Hashtable<String, String>(10);
	@MockDataGenerationField(minimumStringLength=32, maximumStringLength=1024)
	private String radiologyReport = null;
	@MockDataGenerationField(pattern=MockDataGenerationField.NAME_PATTERN)
	private String patientName;
	@MockDataGenerationField(pattern=MockDataGenerationField.UID_PATTERN)
	private String studyUid; // dicom UID
	private String firstImageIen;
	@MockDataGenerationField(pattern="[A-Z][a-z]{4,16}, [A-Z][a-z]")
	private String siteName;
	@MockDataGenerationField(pattern="[1-9][0-9][0-9]")
	private String siteAbbr;
	@MockDataGenerationField(componentValueType="gov.va.med.imaging.exchange.business.Series")
	private Set<Series> series = new TreeSet<Series>(new SeriesComparator());
	private Image firstImage;
	@MockDataGenerationField(pattern="[A-Z][a-z][0-9] [A-Z][a-z][0-9] [A-Z][a-z][0-9] [A-Z][a-z][0-9] [A-Z][a-z][0-9]")
	private String rpcResponseMsg;
	private Set<String> modalities = null;
	@MockDataGenerationField(minimumDate="01-01-1990", maximumDate="12-31-2010")
	private Date procedureDate;
	@MockDataGenerationField(pattern="[A-Z][a-z][0-9] [A-Z][a-z][0-9] [A-Z][a-z][0-9] [A-Z][a-z][0-9] [A-Z][a-z][0-9]")
	private String errorMessage;
	private String alienSiteNumber;

	private ObjectStatus studyStatus = ObjectStatus.NO_STATUS;
	private ObjectStatus studyViewStatus = ObjectStatus.NO_STATUS;
	private boolean sensitive = false;
	private Date documentDate = null;
	private String cptCode = null;
	private String consolidatedSiteNumber = null;
	// if this object was created by cloning another object and changing the site number, then hold onto the old identifier just in case
	private GlobalArtifactIdentifier alternateArtifactIdentifier = null;
	private boolean studyImagesHaveAnnotations = false;

	//NOTE: If you add more fields to this class, be sure to add the new fields to cloneWithConsolidatedSiteNumber()
	// to ensure the new fields are copied correctly

	/**
	 *
	 * @param objectOrigin
	 * @param siteNumber
	 * @param studyIen
	 * @param studyLoadLevel
	 * @return
	 * @throws URNFormatException
	 */
	public static Study create(
		ObjectOrigin objectOrigin,
		String repositoryId,
		String studyIen,
		PatientIdentifier patientIdentifier,
		StudyLoadLevel studyLoadLevel,
		StudyDeletedImageState studyDeletedImageState)
	throws URNFormatException
	{
		if(objectOrigin == null)
		{
			Logger.getLogger(Study.class).error("Unable to create Study instance because object origin is null.");
			return null;
		}
		if(repositoryId == null)
		{
			Logger.getLogger(Study.class).error("Unable to create Study instance because repository ID is null.");
			return null;
		}
		if(studyIen == null)
		{
			Logger.getLogger(Study.class).error("Unable to create Study instance because Study IEN is null.");
			return null;
		}
		if(patientIdentifier == null)
		{
			Logger.getLogger(Study.class).error("Unable to create Study instance because Patient ID is null.");
			return null;
		}
		if(studyLoadLevel == null)
		{
			Logger.getLogger(Study.class).error("Unable to create Study instance because given StudyLoadLevel is null.");
			return null;
		}

		StudyURN studyUrn = StudyURNFactory.create(repositoryId, studyIen, patientIdentifier.getValue(), StudyURN.class);
		// set the patient identifier type if it is necessary
		studyUrn.setPatientIdentifierTypeIfNecessary(patientIdentifier.getPatientIdentifierType());
		return create(studyUrn, studyLoadLevel, studyDeletedImageState);
	}

	/**
	 *
	 * @param identifier
	 * @return
	 */
	public static Study create(GlobalArtifactIdentifier identifier, StudyLoadLevel studyLoadLevel,
			StudyDeletedImageState studyDeletedImageState)
	{
		if(identifier == null)
		{
			Logger.getLogger(Study.class).error("Unable to create Study instance because given identifier is null.");
			return null;
		}
		if(studyLoadLevel == null)
		{
			Logger.getLogger(Study.class).error("Unable to create Study instance because given StudyLoadLevel is null.");
			return null;
		}

		return new Study(identifier, studyLoadLevel, studyDeletedImageState);
	}

	/*
	 * private int imageCount; private String noteTitle; private String
	 * imagePackage; private String imageType; private String specialty; private
	 * String event; // event title private String origin; // VA, DOD, FEE,
	 * NON-VA private String captureDate; // date image captured private String
	 * captureBy; // empty if coming from Gateway
	 */
	private Study(GlobalArtifactIdentifier globalArtifactIdentifier, StudyLoadLevel studyLoadLevel,
			StudyDeletedImageState studyDeletedImageState)
	{
		this.globalArtifactIdentifier = globalArtifactIdentifier;
		this.studyLoadLevel = studyLoadLevel;
		this.studyDeletedImageState = studyDeletedImageState;

		radiologyReport = patientName = studyUid = firstImageIen = siteName = siteAbbr = "";
		modalities = new TreeSet<String>();
		/*
		 * imageCount = 0; noteTitle = imagePackage = imageType = specialty =
		 * event = origin = captureBy = captureDate = "";
		 */
		errorMessage = "";
		alienSiteNumber = "";

	}

	/**
	 * Get the unique identifier of this Study
	 * @return
	 */
	public GlobalArtifactIdentifier getGlobalArtifactIdentifier()
	{
		return this.globalArtifactIdentifier;
	}

	public int getSeriesCount()
	{
		return this.series.size();
	}

	public Set<Series> getSeries()
	{
		return series;
	}

	public void addSeries(Series series)
	{
		this.series.add(series);
	}

	@Override
	public Iterator<Series> iterator()
	{
		return series.iterator();
	}

	/**
	 * Return a child Series from the series (group) IEN.
	 * Returns null if the Series identified by the IEN is not a child.
	 * Returns null if seriesIen is null.
	 *
	 * @param seriesIen
	 * @return
	 */
	public Series getChildSeries(String seriesIen)
	{
		if(seriesIen == null || getSeries() == null)
			return null;

		for(Series series : getSeries())
			if( seriesIen.equals(series.getSeriesIen()) )
				return series;

		return null;
	}

	public void setValue(String key, String value)
	{
		studyValues.put(key, value);
	}

	public String getValue(String key)
	{
		String value = studyValues.get(key);
		return value == null ? "" : value;
	}

	public void setValue(String key, int value)
	{
		studyValues.put(key, Integer.toString(value));
	}

	public int getValueAsInt(String key)
	{
		String value = studyValues.get(key);
		int valueAsInt = 0;
		if (value != null)
		{
			valueAsInt = Integer.parseInt(value);
		}
		return valueAsInt;
	}

	public Enumeration<String> getKeys()
	{
		return studyValues.keys();
	}

	// getters and setters for Study dynamic properties
	public String getProcedure()
	{
		return getValue("Procedure");
	}

	public void setProcedure(String procedure)
	{
		setValue("Procedure", procedure);
	}

//  public int getImageCount() {
//  return getValueAsInt("# Img");
//}

	public int getImageCount() {
	    // CPT -- 07/17/08: make sure all series' image counts added up for multiple groups
	    int numImages = 0;
	    Set<Series> seriesSet = this.getSeries();
	    if(seriesSet != null && seriesSet.size() > 1) {
	          for(Iterator<Series> seriesIter = seriesSet.iterator(); seriesIter.hasNext(); )
	          {
	                Series series = seriesIter.next();
	                numImages += series.getImageCount();
	          }
	    } else { // no series in study ??
	          numImages = getValueAsInt("# Img");
	    }
	    return numImages;
	}

	public void setImageCount(int imageCount)
	{
		setValue("# Img", imageCount);
	}

	public String getNoteTitle()
	{
		return getValue("Note Title");
	}

	public void setNoteTitle(String noteTitle)
	{
		setValue("Note Title", noteTitle);
	}

	public String getImagePackage()
	{
		return getValue("Pkg");
	}

	public void setImagePackage(String imagePackage)
	{
		setValue("Pkg", imagePackage);
	}

	public String getImageType()
	{
		return getValue("Type");
	}

	public void setImageType(String imageType)
	{
		setValue("Type", imageType);
	}

	public String getSpecialty()
	{
		return getValue("Specialty");
	}

	public void setSpecialty(String specialty)
	{
		setValue("Specialty", specialty);
	}

	public String getEvent()
	{
		return getValue("Event");
	}

	public void setEvent(String event)
	{
		setValue("Event", event);
	}

	public String getOrigin()
	{
		return getValue("Origin");
	}

	public void setOrigin(String origin)
	{
		setValue("Origin", origin);
	}

	public String getCaptureDate()
	{
		return getValue("Cap Dt");
	}

	public void setCaptureDate(String captureDate)
	{
		setValue("Cap Dt", captureDate);
	}

	public String getCaptureBy()
	{
		return getValue("Cap by");
	}

	public void setCaptureBy(String captureBy)
	{
		setValue("Cap by", captureBy);
	}

	public String getRadiologyReport()
	{
		return radiologyReport;
	}

	public void setRadiologyReport(String radiologyReport)
	{
		// JMW 9/30/2010 P104
		// if the report is set, ensure the StudyLoadLevel represents that information
		if(radiologyReport != null)
		{
			this.studyLoadLevel = StudyLoadLevel.promoteWithReport(this.studyLoadLevel);
		}
		this.radiologyReport = radiologyReport;
	}

	public void setProcedureDate(Date procedureDate)
	{
		this.procedureDate = procedureDate;
	}

	public String getProcedureDateString()
	{
		return getValue("Proc DT");
	}

	public void setProcedureDateString(String value)
	{
		setValue("Proc DT", value);
	}

	public Date getProcedureDate()
	{
		return this.procedureDate;
	}

	public void setDescription(String description)
	{
		setValue("Short Desc", description);
	}

	public String getDescription()
	{
		return getValue("Short Desc");
	}

	public void setStudyClass(String studyClass)
	{
		setValue("Class", studyClass);
	}

	public String getStudyClass()
	{
		return getValue("Class");
	}

	/**
	 * If this is a VA Study then the patient ICN is in the global artifact identifier,
	 * else we don't have it.
	 *
	 * @return the patientIcn
	 */
	public String getPatientId()
	{
		GlobalArtifactIdentifier gai = getGlobalArtifactIdentifier();
		if(gai instanceof StudyURN)
			return ((StudyURN)gai).getPatientId();
		if(gai instanceof BhieStudyURN)
			return ((BhieStudyURN)gai).getPatientId();

		return null;
	}

	public PatientIdentifier getPatientIdentifier()
	{
		String patientId = getPatientId();
		PatientIdentifierType patientIdentifierType = getPatientIdentifierType();
		if(patientId == null || patientIdentifierType == null)
			return null;

		return new PatientIdentifier(patientId, patientIdentifierType);
	}

	public PatientIdentifierType getPatientIdentifierType()
	{
		GlobalArtifactIdentifier gai = getGlobalArtifactIdentifier();
		if(gai instanceof StudyURN)
			return ((StudyURN)gai).getPatientIdentifierTypeOrDefault();
		if(gai instanceof BhieStudyURN)
			return ((BhieStudyURN)gai).getPatientIdentifierTypeOrDefault();

		return null;
	}

	/**
	 * If this is a VA Study then the study IEN is in the global artifact identifier,
	 * else we don't have it and the correct thing to ask for is the documentIdentifier
	 *
	 * @return the studyIen
	 */
	public String getStudyIen()
	{
		GlobalArtifactIdentifier gai = getGlobalArtifactIdentifier();
		if(gai instanceof StudyURN)
			return ((StudyURN)gai).getGroupId();
		if(gai instanceof BhieStudyURN)
			return ((BhieStudyURN)gai).getDocumentUniqueId();

		return null;
	}

	/**
	 * @return the siteNumber
	 */
	public String getSiteNumber()
	{
		return getGlobalArtifactIdentifier().getRepositoryUniqueId();
	}

	/**
	 * @return the patientName
	 */
	public String getPatientName()
	{
		return patientName;
	}

	/**
	 * @param patientName
	 *            the patientName to set
	 */
	public void setPatientName(String patientName)
	{
		this.patientName = patientName;
	}

	/**
	 * @return the studyUid (the DICOM UID)
	 */
	public String getStudyUid()
	{
		return studyUid;
	}

	/**
	 * @return the firstImageIen
	 */
	public String getFirstImageIen()
	{
		return firstImageIen;
	}

	/**
	 * @param firstImageIen
	 *            the firstImageIen to set
	 */
	public void setFirstImageIen(String firstImageIen)
	{
		this.firstImageIen = firstImageIen;
	}

	/**
	 * @return the siteAbbr
	 */
	public String getSiteAbbr()
	{
		return siteAbbr;
	}

	/**
	 * @param siteAbbr
	 *            the siteAbbr to set
	 */
	public void setSiteAbbr(String siteAbbr)
	{
		this.siteAbbr = siteAbbr;
	}

	/**
	 * @return the siteName
	 */
	public String getSiteName()
	{
		return siteName;
	}

	/**
	 * @param siteName
	 *            the siteName to set
	 */
	public void setSiteName(String siteName)
	{
		this.siteName = siteName;
	}

	/**
	 * @param studyUid
	 *            the studyUid to set
	 */
	public void setStudyUid(String studyUid)
	{
		this.studyUid = studyUid;
	}

	/**
	 * @return the firstImage
	 */
	public Image getFirstImage()
	{
		return firstImage;
	}

	/**
	 * @param firstImage
	 *            the firstImage to set
	 */
	public void setFirstImage(Image firstImage)
	{
		this.firstImage = firstImage;
	}

	/**
	 * @return the rpcResponseMsg
	 */
	public String getRpcResponseMsg()
	{
		return rpcResponseMsg;
	}

	/**
	 * @param rpcResponseMsg
	 *            the rpcResponseMsg to set
	 */
	public void setRpcResponseMsg(String rpcResponseMsg)
	{
		this.rpcResponseMsg = rpcResponseMsg;
	}

	/**
	 * @return the objectOrigin
	 */
	public ObjectOrigin getObjectOrigin()
	{
		return ObjectOrigin.inferFromHomeCommunityId(getGlobalArtifactIdentifier().getHomeCommunityId());
	}

	public StudyURN getStudyUrn()
	{
		return getGlobalArtifactIdentifier() instanceof StudyURN ?
			(StudyURN)getGlobalArtifactIdentifier() : null;
	}

	public void addModality(String modality)
	{
		this.modalities.add(modality);
	}

	public Set<String> getModalities()
	{
		return this.modalities;
	}

	/**
	 * @return the errorMessage
	 */
	public String getErrorMessage() {
		return errorMessage;
	}

	/**
	 * @param errorMessage the errorMessage to set
	 */
	public void setErrorMessage(String errorMessage) {
		this.errorMessage = errorMessage;
	}

	public boolean hasErrorMessage()
	{
		if((errorMessage == null) || (errorMessage.length() <= 0))
			return false;
		return true;
	}

	public boolean isDeleted()
	{
		return (studyViewStatus == ObjectStatus.DELETED);
	}

	/**
	 * The alien site number is the number for a site where the study came from. This number is the number
	 * from the alien data source (DOD).  This is not the site number used internally that exists within the
	 * site service but an external number. This number is not required to be present and should not transmit
	 * across Federation.
	 * @return the alienSiteNumber
	 */
	public String getAlienSiteNumber() {
		return alienSiteNumber;
	}

	/**
	 * @param alienSiteNumber the alienSiteNumber to set
	 */
	public void setAlienSiteNumber(String alienSiteNumber) {
		this.alienSiteNumber = alienSiteNumber;
	}

	/**
	 * @return the studyLoadLevel
	 */
	public StudyLoadLevel getStudyLoadLevel() {
		return studyLoadLevel;
	}

	public ObjectStatus getStudyStatus()
	{
		return studyStatus;
	}

	public void setStudyStatus(ObjectStatus studyStatus)
	{
		this.studyStatus = studyStatus;
	}

	public ObjectStatus getStudyViewStatus()
	{
		return studyViewStatus;
	}

	public void setStudyViewStatus(ObjectStatus studyViewStatus)
	{
		this.studyViewStatus = studyViewStatus;
	}

	public boolean isSensitive()
	{
		return sensitive;
	}

	public void setSensitive(boolean sensitive)
	{
		this.sensitive = sensitive;
	}

	public Date getDocumentDate()
	{
		return documentDate;
	}

	public void setDocumentDate(Date documentDate)
	{
		this.documentDate = documentDate;
	}

	public String getCptCode()
	{
		return cptCode;
	}

	public void setCptCode(String cptCode)
	{
		this.cptCode = cptCode;
	}

	public String getConsolidatedSiteNumber()
	{
		return consolidatedSiteNumber;
	}

	public void setConsolidatedSiteNumber(String consolidatedSiteNumber)
	{
		this.consolidatedSiteNumber = consolidatedSiteNumber;
	}

	public boolean containsConsolidatedSiteNumber()
	{
		if(this.consolidatedSiteNumber == null)
			return false;
		if(this.consolidatedSiteNumber.length() <= 0)
			return false;
		// if the consolidated site number value is the same as the site number, no need to update the value
		// just return false to avoid unnecessary effort
		if(this.consolidatedSiteNumber.equals(this.getSiteNumber()))
			return false;
		return true;
	}

	/**
	 * Needs to be set if the study contains deleted images, to be used to determine if the study objects
	 * can satisfy a request from the client
	 * @return
	 */
	public StudyDeletedImageState getStudyDeletedImageState()
	{
		return studyDeletedImageState;
	}

	public GlobalArtifactIdentifier getAlternateArtifactIdentifier()
	{
		return alternateArtifactIdentifier;
	}

	public void setAlternateArtifactIdentifier(
			GlobalArtifactIdentifier alternateArtifactIdentifier)
	{
		this.alternateArtifactIdentifier = alternateArtifactIdentifier;
	}

	// ==========================================================================
	// StudyFilterFilterable Implementation
	// ==========================================================================
	@Override
	public String getFirstImageClass()
	{
		return getFirstImage() == null ? null : getFirstImage().getImageClass();
	}

	@Override
	public int getFirstImageType()
	{
		return getFirstImage() == null ? -1 : getFirstImage().getImgType();
	}

	public boolean isStudyImagesHaveAnnotations()
	{
		return studyImagesHaveAnnotations;
	}

	public void setStudyImagesHaveAnnotations(boolean studyImagesHaveAnnotations)
	{
		this.studyImagesHaveAnnotations = studyImagesHaveAnnotations;
	}

	/**
	 * The natural ordering of Study instances is defined as: 1.) decreasing by
	 * procedureDate
	 *
	 * @see java.lang.Comparable#compareTo(java.lang.Object)
	 */
	@Override
	public int compareTo(Study that)
	{
		int cumulativeCompare = 0;

		cumulativeCompare = ComparableUtil.compare(this.procedureDate, that.procedureDate, false);
		if(cumulativeCompare != 0)
			return cumulativeCompare;

		return getGlobalArtifactIdentifier().compareTo(that.getGlobalArtifactIdentifier());
	}

	/**
	 * The implementation of hashCode is consistent with the definition in
	 * java.lang.Object, including compatibility with .equals(). The hashCode is
	 * based on the site number and the study IEN, which will provide the
	 * correct behavior and uniqueness if those fields are populated.
	 *
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode()
	{
		final int prime = 31;
		int result = 1;
		result = prime * result
			+ ((this.globalArtifactIdentifier == null) ? 0 : this.globalArtifactIdentifier.hashCode());
		return result;
	}

	/**
	 * The .equals() is based on the site number and the study IEN, which will
	 * provide the correct behavior and uniqueness if those fields are
	 * populated.
	 *
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj)
	{
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final Study other = (Study) obj;
		if (this.globalArtifactIdentifier == null)
		{
			if (other.globalArtifactIdentifier != null)
				return false;
		}
		else if (!this.globalArtifactIdentifier.equalsGlobalArtifactIdentifier(other.globalArtifactIdentifier))
			return false;
		return true;
	}

	/**
	 *
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString()
	{
		StringBuilder sb = new StringBuilder();
		/*
		 * String output = super.toString(); output += "\nStudy Properties:\n";
		 * Enumeration<String> enumeration = studyValues.keys();
		 * while(enumeration.hasMoreElements()) { String key =
		 * enumeration.nextElement(); output += key + ": " +
		 * studyValues.get(key) + "\n"; }
		 */
		sb.append("Study Details [" + this.getGlobalArtifactIdentifier() + "]\t" + "Study UID [" + this.studyUid + "]\n" + "Contains " + series.size()
		        + " series:\n");

		Iterator<Series> seriesIter = series.iterator();
		while (seriesIter.hasNext())
		{
			Series series = seriesIter.next();
			sb.append(series.toString());
		}

		/*
		 * output += "NoteTitle: " + noteTitle + "\n"; output += "ImagePackage: " +
		 * imagePackage + "\n"; output += "ImageType: " + imageType + "\n";
		 * output += "Specialty: " + specialty + "\n"; output += "Event: " +
		 * event + "\n"; output += "Origin: " + origin + "\n"; output +=
		 * "CaptureDate: " + captureDate + "\n"; output += "CapturedBy: " +
		 * captureBy + "\n";
		 */
		return sb.toString();
	}

	/**
	 * This method clones all pieces of the Study and updates the URN with the value from the consolidated site number.
	 * This method should only be called if its been confirmed that the consolidated site number is "valid"
	 * @return
	 */
	public Study cloneWithConsolidatedSiteNumber(Site site)
	{
		if(containsConsolidatedSiteNumber())
		{
			if(!this.getSiteNumber().equals(this.consolidatedSiteNumber))
			{
				StudyURN studyUrn = this.getStudyUrn();
				// if the study URN is null then this is not a VA study and we shouldn't do anything with it
				if(studyUrn != null)
				{
					try
					{

						StudyURN newUrn =
							StudyURNFactory.create(this.consolidatedSiteNumber, studyUrn.getStudyId(),
									studyUrn.getPatientId(), StudyURN.class);
						newUrn.setPatientIdentifierTypeIfNecessary(studyUrn.getPatientIdentifierType());
						logger.debug("Updating study '" + studyUrn.toString() + "' with new site ID, created new URN '" + newUrn.toString() + "'.");
						Study study = new Study(newUrn, this.studyLoadLevel, this.studyDeletedImageState);

						study.alienSiteNumber = this.alienSiteNumber;
						study.consolidatedSiteNumber = this.consolidatedSiteNumber;
						study.cptCode = this.cptCode;
						study.documentDate = this.documentDate;
						study.errorMessage = this.errorMessage;
						study.firstImage = this.firstImage;
						study.firstImageIen = this.firstImageIen;
						study.modalities = this.modalities;
						study.patientName = this.patientName;
						study.procedureDate = this.procedureDate;
						study.radiologyReport = this.radiologyReport;
						study.rpcResponseMsg = this.rpcResponseMsg;
						study.sensitive = this.sensitive;
						study.series = this.series;
						// really need to update these!
						study.siteAbbr = this.siteAbbr; // don't update this because it should be correct from VistA
						study.siteName = site.getSiteName();
						study.studyStatus = this.studyStatus;
						study.studyUid = this.studyUid;
						study.studyValues.putAll(this.studyValues);
						study.studyViewStatus = this.studyViewStatus;
						study.alternateArtifactIdentifier = studyUrn;
						study.studyImagesHaveAnnotations = this.studyImagesHaveAnnotations;

						// add the series to the study, don't update the image objects because they could
						// have different consolidated site numbers than the study
						// updating the images happens elsewhere
						for(Series series : this)
						{
							study.addSeries(series);
						}

						return study;
					}
					catch(URNFormatException urnfX)
					{
						logger.warn("Error creating new StudyURN from consolidated site number, " + urnfX.getMessage(), urnfX);
					}
				}
			}
		}
		// if we get here then either something went wrong or the conversion was not necessary
		return this;
	}

}