text:
#ifndef _EXYNOS_IOMMU_H_
#define _EXYNOS_IOMMU_H_

#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/genalloc.h>
#include <linux/iommu.h>
#include <linux/irq.h>
#include <linux/clk.h>

#include <linux/exynos_iovmm.h>

#include <mach/bts.h>

#include "exynos-iommu-log.h"

#define TRACE_LOG(...) do { } while (0) /* trace_printk */
#define TRACE_LOG_DEV(dev, fmt, args...)  \
		TRACE_LOG("%s: " fmt, dev_name(dev), ##args)

#define MODULE_NAME "exynos-sysmmu"

#define IOVA_START 0x10000000
#define IOVM_SIZE (SZ_2G + SZ_1G + SZ_256M) /* last 4K is for error values */

#define IOVM_NUM_PAGES(vmsize) (vmsize / PAGE_SIZE)
#define IOVM_BITMAP_SIZE(vmsize) \
		((IOVM_NUM_PAGES(vmsize) + BITS_PER_BYTE) / BITS_PER_BYTE)

#define SPSECT_ORDER	24
#define DSECT_ORDER	21
#define SECT_ORDER	20
#define LPAGE_ORDER	16
#define SPAGE_ORDER	12

#define SPSECT_SIZE	(1 << SPSECT_ORDER)
#define DSECT_SIZE	(1 << DSECT_ORDER)
#define SECT_SIZE	(1 << SECT_ORDER)
#define LPAGE_SIZE	(1 << LPAGE_ORDER)
#define SPAGE_SIZE	(1 << SPAGE_ORDER)

#define SPSECT_MASK	~(SPSECT_SIZE - 1)
#define DSECT_MASK	~(DSECT_SIZE - 1)
#define SECT_MASK	~(SECT_SIZE - 1)
#define LPAGE_MASK	~(LPAGE_SIZE - 1)
#define SPAGE_MASK	~(SPAGE_SIZE - 1)

#define SPSECT_ENT_MASK	~((SPSECT_SIZE >> PG_ENT_SHIFT) - 1)
#define DSECT_ENT_MASK	~((DSECT_SIZE >> PG_ENT_SHIFT) - 1)
#define SECT_ENT_MASK	~((SECT_SIZE >> PG_ENT_SHIFT) - 1)
#define LPAGE_ENT_MASK	~((LPAGE_SIZE >> PG_ENT_SHIFT) - 1)
#define SPAGE_ENT_MASK	~((SPAGE_SIZE >> PG_ENT_SHIFT) - 1)

#define SECT_PER_SPSECT		(SPSECT_SIZE / SECT_SIZE)
#define SECT_PER_DSECT		(DSECT_SIZE / SECT_SIZE)
#define SPAGES_PER_LPAGE	(LPAGE_SIZE / SPAGE_SIZE)

#define PGBASE_TO_PHYS(pgent)	((phys_addr_t)(pgent) << PG_ENT_SHIFT)

#define MAX_NUM_PBUF	6
#define MAX_NUM_PLANE	6

#define NUM_LV1ENTRIES 4096
#define NUM_LV2ENTRIES (SECT_SIZE / SPAGE_SIZE)

#define lv1ent_offset(iova) ((iova) >> SECT_ORDER)
#define lv2ent_offset(iova) ((iova & ~SECT_MASK) >> SPAGE_ORDER)

typedef u32 sysmmu_pte_t;

#define LV2TABLE_SIZE (NUM_LV2ENTRIES * sizeof(sysmmu_pte_t))

#define ENT_TO_PHYS(ent) (phys_addr_t)(*(ent))
#define spsection_phys(sent) PGBASE_TO_PHYS(ENT_TO_PHYS(sent) & SPSECT_ENT_MASK)
#define spsection_offs(iova) ((iova) & (SPSECT_SIZE - 1))
#define section_phys(sent) PGBASE_TO_PHYS(ENT_TO_PHYS(sent) & SECT_ENT_MASK)
#define section_offs(iova) ((iova) & (SECT_SIZE - 1))
#define lpage_phys(pent) PGBASE_TO_PHYS(ENT_TO_PHYS(pent) & LPAGE_ENT_MASK)
#define lpage_offs(iova) ((iova) & (LPAGE_SIZE - 1))
#define spage_phys(pent) PGBASE_TO_PHYS(ENT_TO_PHYS(pent) & SPAGE_ENT_MASK)
#define spage_offs(iova) ((iova) & (SPAGE_SIZE - 1))

#define lv2table_base(sent) ((phys_addr_t)(*(sent) & ~0x3F) << PG_ENT_SHIFT)

#define SYSMMU_BLOCK_POLLING_COUNT 4096

#define REG_MMU_CTRL		0x000
#define REG_MMU_CFG		0x004
#define REG_MMU_STATUS		0x008
#define REG_MMU_VERSION		0x034

#define CTRL_ENABLE	0x5
#define CTRL_BLOCK	0x7
#define CTRL_DISABLE	0x0
#define CTRL_BLOCK_DISABLE 0x3

#define CFG_ACGEN	(1 << 24) /* System MMU 3.3+ */
#define CFG_FLPDCACHE	(1 << 20) /* System MMU 3.2+ */
#define CFG_SHAREABLE	(1 << 12) /* System MMU 3.0+ */
#define CFG_QOS_OVRRIDE (1 << 11) /* System MMU 3.3+ */
#define CFG_QOS(n)	(((n) & 0xF) << 7)

/*
 * Metadata attached to the owner of a group of System MMUs that belong
 * to the same owner device.
 */
struct exynos_iommu_owner {
	struct list_head client; /* entry of exynos_iommu_domain.clients */
	struct device *dev;
	struct exynos_iommu_owner *next; /* linked list of Owners */
	void *vmm_data;         /* IO virtual memory manager's data */
	spinlock_t lock;        /* Lock to preserve consistency of System MMU */
	struct list_head mmu_list; /* head of sysmmu_list_data.node */
#ifdef CONFIG_EXYNOS_IOMMU_V6
	struct notifier_block nb;
	iommu_fault_handler_t fault_handler;
	void *token;
#endif
};

struct exynos_vm_region {
	struct list_head node;
	u32 start;
	u32 size;
	u32 section_off;
	u32 dummy_size;
};

struct exynos_iovmm {
	struct iommu_domain *domain; /* iommu domain for this iovmm */
	size_t iovm_size[MAX_NUM_PLANE]; /* iovm bitmap size per plane */
	u32 iova_start[MAX_NUM_PLANE]; /* iovm start address per plane */
	unsigned long *vm_map[MAX_NUM_PLANE]; /* iovm biatmap per plane */
	struct list_head regions_list;	/* list of exynos_vm_region */
	spinlock_t vmlist_lock; /* lock for updating regions_list */
	spinlock_t bitmap_lock; /* lock for manipulating bitmaps */
	struct device *dev; /* peripheral device that has this iovmm */
	size_t allocated_size[MAX_NUM_PLANE];
	int num_areas[MAX_NUM_PLANE];
	int inplanes;
	int onplanes;
	unsigned int num_map;
	unsigned int num_unmap;
	const char *domain_name;
#ifdef CONFIG_EXYNOS_IOMMU_EVENT_LOG
	struct exynos_iommu_event_log log;
#endif
};

void exynos_sysmmu_tlb_invalidate(struct iommu_domain *domain, dma_addr_t start,
				  size_t size);

#define SYSMMU_FAULT_WRITE	(1 << SYSMMU_FAULTS_NUM)

enum sysmmu_property {
	SYSMMU_PROP_RESERVED,
	SYSMMU_PROP_READ,
	SYSMMU_PROP_WRITE,
	SYSMMU_PROP_READWRITE = SYSMMU_PROP_READ | SYSMMU_PROP_WRITE,
	SYSMMU_PROP_RW_MASK = SYSMMU_PROP_READWRITE,
	SYSMMU_PROP_NONBLOCK_TLBINV = 0x10,
	SYSMMU_PROP_STOP_BLOCK = 0x20,
	SYSMMU_PROP_WINDOW_SHIFT = 16,
	SYSMMU_PROP_WINDOW_MASK = 0x1F << SYSMMU_PROP_WINDOW_SHIFT,
};

enum sysmmu_clock_ids {
	SYSMMU_ACLK,
	SYSMMU_PCLK,
	SYSMMU_MASTER,
	SYSMMU_CLK_NUM,
};

/*
 * Metadata attached to each System MMU devices.
 */
struct sysmmu_drvdata {
	struct list_head node;	/* entry of exynos_iommu_owner.mmu_list */
	struct list_head pb_grp_list;	/* list of pb groups */
	struct sysmmu_drvdata *next; /* linked list of System MMU */
	struct device *sysmmu;	/* System MMU's device descriptor */
	struct device *master;	/* Client device that needs System MMU */
	void __iomem *sfrbase;
	struct clk *clocks[SYSMMU_CLK_NUM];
	int activations;
	struct iommu_domain *domain; /* domain given to iommu_attach_device() */
	phys_addr_t pgtable;
	spinlock_t lock;
	struct sysmmu_prefbuf pbufs[MAX_NUM_PBUF];
	short qos;
	short num_pbufs;
	int runtime_active;
	bool suspended;
	enum sysmmu_property prop; /* mach/sysmmu.h */
#ifdef CONFIG_EXYNOS_IOMMU_EVENT_LOG
	struct exynos_iommu_event_log log;
#endif
#ifdef CONFIG_EXYNOS_IOMMU_V6
	struct atomic_notifier_head fault_notifiers;
#endif
	unsigned char event_cnt;
};

struct exynos_iommu_domain {
	struct list_head clients; /* list of sysmmu_drvdata.node */
	sysmmu_pte_t *pgtable; /* lv1 page table, 16KB */
	atomic_t *lv2entcnt; /* free lv2 entry counter for each section */
	spinlock_t lock; /* lock for this structure */
	spinlock_t pgtablelock; /* lock for modifying page table @ pgtable */
#ifdef CONFIG_EXYNOS_IOMMU_EVENT_LOG
	struct exynos_iommu_event_log log;
#endif
};

struct pb_info {
	struct list_head node;
	int ar_id_num;
	int aw_id_num;
	int grp_num;
	int ar_axi_id[MAX_NUM_PBUF];
	int aw_axi_id[MAX_NUM_PBUF];
	struct device *master;
	enum sysmmu_property prop;
};

int sysmmu_set_ppc_event(struct sysmmu_drvdata *drvdata, int event);
void dump_sysmmu_ppc_cnt(struct sysmmu_drvdata *drvdata);
extern const char *ppc_event_name[];

#if defined(CONFIG_EXYNOS7_IOMMU) && defined(CONFIG_EXYNOS5_IOMMU)
#error "CONFIG_IOMMU_EXYNOS5 and CONFIG_IOMMU_EXYNOS7 defined together"
#endif

#if defined(CONFIG_EXYNOS5_IOMMU) /* System MMU v1/2/3 */

#define REG_PPC_PMNC		0x800
#define REG_PPC_CNTENS		0x810
#define REG_PPC_CNTENC		0x820
#define REG_PPC_INTENS		0x830
#define REG_PPC_INTENC		0x840
#define REG_PPC_FLAG		0x850
#define REG_PPC_CCNT		0x900
#define REG_PPC_PMCNT(x)	(0x910 + 0x10 * (x))
#define REG_PPC_EVENT_SEL(offset, cnt)	((offset) + 0x4 * (cnt))

#define SYSMMU_OF_COMPAT_STRING "samsung,exynos4210-sysmmu"
#define DEFAULT_QOS_VALUE	8
#define PG_ENT_SHIFT 0 /* 32bit PA, 32bit VA */
#define lv1ent_fault(sent) ((*(sent) == ZERO_LV2LINK) || \
			   ((*(sent) & 3) == 0) || ((*(sent) & 3) == 3))
#define lv1ent_page(sent) ((*(sent) != ZERO_LV2LINK) && \
			  ((*(sent) & 3) == 1))
#define lv1ent_section(sent) ((*(sent) & 3) == 2)
#define lv1ent_dsection(sent) 0 /* Large section is not defined */
#define lv1ent_spsection(sent) (((*(sent) & 3) == 2) && \
			       (((*(sent) >> 18) & 1) == 1))
#define lv2ent_fault(pent) ((*(pent) & 3) == 0 || \
			   ((*(pent) & SPAGE_ENT_MASK) == fault_page))
#define lv2ent_small(pent) ((*(pent) & 2) == 2)
#define lv2ent_large(pent) ((*(pent) & 3) == 1)
#define dsection_phys(sent) ({ BUG(); 0; }) /* large section is not defined */
#define dsection_offs(iova) ({ BUG(); 0; })
#define mk_lv1ent_spsect(pa) ((sysmmu_pte_t) ((pa) | 0x40002))
#define mk_lv1ent_dsect(pa) ({ BUG(); 0; })
#define mk_lv1ent_sect(pa) ((sysmmu_pte_t) ((pa) | 2))
#define mk_lv1ent_page(pa) ((sysmmu_pte_t) ((pa) | 1))
#define mk_lv2ent_lpage(pa) ((sysmmu_pte_t) ((pa) | 1))
#define mk_lv2ent_spage(pa) ((sysmmu_pte_t) ((pa) | 2))
#define set_lv1ent_shareable(sent) (*(sent) |= (1 << 16))
#define set_lv2ent_shareable(pent) (*(pent) |= (1 << 10))

#define PGSIZE_BITMAP (SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE)

#define __exynos_sysmmu_set_df(drvdata, iova) do { } while (0)
#define __exynos_sysmmu_release_df(drvdata) do { } while (0)

 /* System MMU v5 ~ */
#elif defined(CONFIG_EXYNOS7_IOMMU) || defined(CONFIG_EXYNOS_IOMMU_V6)

#define REG_PPC_EVENT_SEL(x)	(0x600 + 0x4 * (x))
#define REG_PPC_PMNC		0x620
#define REG_PPC_CNTENS		0x624
#define REG_PPC_CNTENC		0x628
#define REG_PPC_INTENS		0x62C
#define REG_PPC_INTENC		0x630
#define REG_PPC_FLAG		0x634
#define REG_PPC_CCNT		0x640
#define REG_PPC_PMCNT(x)	(0x644 + 0x4 * (x))

#define SYSMMU_OF_COMPAT_STRING "samsung,exynos5430-sysmmu"
#define DEFAULT_QOS_VALUE	-1 /* Inherited from master */
#define PG_ENT_SHIFT 4 /* 36bit PA, 32bit VA */
#ifndef CONFIG_EXYNOS_IOMMU_V6
#define lv1ent_fault(sent) ((*(sent) == ZERO_LV2LINK) || \
			   ((*(sent) & 7) == 0))
#define lv1ent_page(sent) ((*(sent) != ZERO_LV2LINK) && \
			  ((*(sent) & 7) == 1))
#else
#define lv1ent_fault(sent) ((*(sent) & 7) == 0)
#define lv1ent_page(sent) ((*(sent) & 7) == 1)
#endif
#define lv1ent_section(sent) ((*(sent) & 7) == 2)
#define lv1ent_dsection(sent) ((*(sent) & 7) == 4)
#define lv1ent_spsection(sent) ((*(sent) & 7) == 6)
#define lv2ent_fault(pent) ((*(pent) & 3) == 0 || \
			   (PGBASE_TO_PHYS(*(pent) & SPAGE_ENT_MASK) == fault_page))
#define lv2ent_small(pent) ((*(pent) & 2) == 2)
#define lv2ent_large(pent) ((*(pent) & 3) == 1)
#define dsection_phys(sent) PGBASE_TO_PHYS(*(sent) & DSECT_ENT_MASK)
#define dsection_offs(iova) ((iova) & (DSECT_SIZE - 1))
#define mk_lv1ent_spsect(pa) ((sysmmu_pte_t) ((pa) >> PG_ENT_SHIFT) | 6)
#define mk_lv1ent_dsect(pa) ((sysmmu_pte_t) ((pa) >> PG_ENT_SHIFT) | 4)
#define mk_lv1ent_sect(pa) ((sysmmu_pte_t) ((pa) >> PG_ENT_SHIFT) | 2)
#define mk_lv1ent_page(pa) ((sysmmu_pte_t) ((pa) >> PG_ENT_SHIFT) | 1)
#define mk_lv2ent_lpage(pa) ((sysmmu_pte_t) ((pa) >> PG_ENT_SHIFT) | 1)
#define mk_lv2ent_spage(pa) ((sysmmu_pte_t) ((pa) >> PG_ENT_SHIFT) | 2)
#define set_lv1ent_shareable(sent) (*(sent) |= (1 << 6))
#define set_lv2ent_shareable(pent) (*(pent) |= (1 << 4))

#define PGSIZE_BITMAP (DSECT_SIZE | SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE)

void __sysmmu_show_status(struct sysmmu_drvdata *drvdata);
void __exynos_sysmmu_set_df(struct sysmmu_drvdata *drvdata, dma_addr_t iova);
void __exynos_sysmmu_release_df(struct sysmmu_drvdata *drvdata);

#else
#error "Neither CONFIG_IOMMU_EXYNOS5 nor CONFIG_IOMMU_EXYNOS7 is defined"
#endif

static inline void __sysmmu_clk_enable(struct sysmmu_drvdata *data)
{
	if (!IS_ERR(data->clocks[SYSMMU_ACLK]))
		clk_enable(data->clocks[SYSMMU_ACLK]);

	if (!IS_ERR(data->clocks[SYSMMU_PCLK]))
		clk_enable(data->clocks[SYSMMU_PCLK]);
}

static inline void __sysmmu_clk_disable(struct sysmmu_drvdata *data)
{
	if (!IS_ERR(data->clocks[SYSMMU_ACLK]))
		clk_disable(data->clocks[SYSMMU_ACLK]);

	if (!IS_ERR(data->clocks[SYSMMU_PCLK]))
		clk_disable(data->clocks[SYSMMU_PCLK]);
}

static inline void __master_clk_enable(struct sysmmu_drvdata *data)
{
	if (!IS_ERR(data->clocks[SYSMMU_MASTER]))
		clk_enable(data->clocks[SYSMMU_MASTER]);
}

static inline void __master_clk_disable(struct sysmmu_drvdata *data)
{
	if (!IS_ERR(data->clocks[SYSMMU_MASTER]))
		clk_disable(data->clocks[SYSMMU_MASTER]);
}

#if defined(CONFIG_EXYNOS7_IOMMU) && defined(CONFIG_EXYNOS5_IOMMU)
#error "CONFIG_IOMMU_EXYNOS5 and CONFIG_IOMMU_EXYNOS7 defined together"
#endif

static inline bool get_sysmmu_runtime_active(struct sysmmu_drvdata *data)
{
	return ++data->runtime_active == 1;
}

static inline bool put_sysmmu_runtime_active(struct sysmmu_drvdata *data)
{
	BUG_ON(data->runtime_active < 1);
	return --data->runtime_active == 0;
}

static inline bool is_sysmmu_runtime_active(struct sysmmu_drvdata *data)
{
	return data->runtime_active > 0;
}

static inline bool set_sysmmu_active(struct sysmmu_drvdata *data)
{
	/* return true if the System MMU was not active previously
	   and it needs to be initialized */
	return ++data->activations == 1;
}

static inline bool set_sysmmu_inactive(struct sysmmu_drvdata *data)
{
	/* return true if the System MMU is needed to be disabled */
	BUG_ON(data->activations < 1);
	return --data->activations == 0;
}

static inline bool is_sysmmu_active(struct sysmmu_drvdata *data)
{
	return data->activations > 0;
}

static inline bool is_sysmmu_really_enabled(struct sysmmu_drvdata *data)
{
	return is_sysmmu_active(data) && data->runtime_active;
}

#define MMU_MAJ_VER(val)	((val) >> 7)
#define MMU_MIN_VER(val)	((val) & 0x7F)
#define MMU_RAW_VER(reg)	(((reg) >> 21) & ((1 << 11) - 1)) /* 11 bits */

#define MAKE_MMU_VER(maj, min)	((((maj) & 0xF) << 7) | ((min) & 0x7F))

static inline unsigned int __raw_sysmmu_version(void __iomem *sfrbase)
{
	return MMU_RAW_VER(__raw_readl(sfrbase + REG_MMU_VERSION));
}

static inline void __raw_sysmmu_disable(void __iomem *sfrbase, int disable)
{
	__raw_writel(0, sfrbase + REG_MMU_CFG);
	__raw_writel(disable, sfrbase + REG_MMU_CTRL);
	BUG_ON(__raw_readl(sfrbase + REG_MMU_CTRL) != disable);
}

static inline void __raw_sysmmu_enable(void __iomem *sfrbase)
{
	__raw_writel(CTRL_ENABLE, sfrbase + REG_MMU_CTRL);
}

#define sysmmu_unblock __raw_sysmmu_enable

void dump_sysmmu_tlb_pb(void __iomem *sfrbase);

static inline bool sysmmu_block(void __iomem *sfrbase)
{
	int i = SYSMMU_BLOCK_POLLING_COUNT;

	__raw_writel(CTRL_BLOCK, sfrbase + REG_MMU_CTRL);
	while ((i > 0) && !(__raw_readl(sfrbase + REG_MMU_STATUS) & 1))
		--i;

	if (!(__raw_readl(sfrbase + REG_MMU_STATUS) & 1)) {
		dump_sysmmu_tlb_pb(sfrbase);
#if defined(CONFIG_EXYNOS5430_BTS)
		exynos5_bts_show_mo_status();
#endif
		panic("Failed to block System MMU!");
		sysmmu_unblock(sfrbase);
		return false;
	}

	return true;
}

void __sysmmu_init_config(struct sysmmu_drvdata *drvdata);
void __sysmmu_set_ptbase(void __iomem *sfrbase, phys_addr_t pfn_pgtable);

extern sysmmu_pte_t *zero_lv2_table;
#define ZERO_LV2LINK mk_lv1ent_page(virt_to_phys(zero_lv2_table))

static inline sysmmu_pte_t *page_entry(sysmmu_pte_t *sent, unsigned long iova)
{
	return (sysmmu_pte_t *)(phys_to_virt(lv2table_base(sent))) +
				lv2ent_offset(iova);
}

static inline sysmmu_pte_t *section_entry(
				sysmmu_pte_t *pgtable, unsigned long iova)
{
	return (sysmmu_pte_t *)(pgtable + lv1ent_offset(iova));
}

irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id);
void __sysmmu_tlb_invalidate_flpdcache(void __iomem *sfrbase, dma_addr_t iova);
void __sysmmu_tlb_invalidate_entry(void __iomem *sfrbase, dma_addr_t iova);
void __sysmmu_tlb_invalidate(struct sysmmu_drvdata *drvdata,
				dma_addr_t iova, size_t size);
#if defined(CONFIG_EXYNOS_IOMMU)
void __exynos_sysmmu_set_prefbuf_by_plane(struct sysmmu_drvdata *drvdata,
			unsigned int inplanes, unsigned int onplanes,
			unsigned int ipoption, unsigned int opoption);
void __exynos_sysmmu_set_prefbuf_by_region(struct sysmmu_drvdata *drvdata,
			struct sysmmu_prefbuf pb_reg[],
			unsigned int num_reg);
int __prepare_prefetch_buffers_by_plane(struct sysmmu_drvdata *drvdata,
				struct sysmmu_prefbuf prefbuf[], int num_pb,
				int inplanes, int onplanes,
				int ipoption, int opoption);
#endif

void dump_sysmmu_tlb_pb(void __iomem *sfrbase);

#if defined(CONFIG_EXYNOS_IOVMM) || defined(CONFIG_EXYNOS_IOVMM_V6)
static inline struct exynos_iovmm *exynos_get_iovmm(struct device *dev)
{
	if (!dev->archdata.iommu) {
		dev_err(dev, "%s: System MMU is not configured\n", __func__);
		return NULL;
	}

	return ((struct exynos_iommu_owner *)dev->archdata.iommu)->vmm_data;
}

struct exynos_vm_region *find_iovm_region(struct exynos_iovmm *vmm,
						dma_addr_t iova);

static inline int find_iovmm_plane(struct exynos_iovmm *vmm, dma_addr_t iova)
{
	int i;

	for (i = 0; i < (vmm->inplanes + vmm->onplanes); i++)
		if ((iova >= vmm->iova_start[i]) &&
			(iova < (vmm->iova_start[i] + vmm->iovm_size[i])))
			return i;
	return -1;
}

#if defined(CONFIG_EXYNOS_IOVMM_V6)
struct exynos_iovmm *exynos_create_single_iovmm(const char *name);
int exynos_sysmmu_add_fault_notifier(struct device *dev,
		iommu_fault_handler_t handler, void *token);
#endif
#else
static inline struct exynos_iovmm *exynos_get_iovmm(struct device *dev)
{
	return NULL;
}

struct exynos_vm_region *find_iovm_region(struct exynos_iovmm *vmm,
						dma_addr_t iova)
{
	return NULL;
}

static inline int find_iovmm_plane(struct exynos_iovmm *vmm, dma_addr_t iova)
{
	return -1;
}

static inline struct exynos_iovmm *exynos_create_single_iovmm(const char *name)
{
	return NULL;
}
#endif /* CONFIG_EXYNOS_IOVMM */

#endif /* _EXYNOS_IOMMU_H_ */


text:
package org.opencompare.ui;

import java.awt.Component;
import java.awt.Frame;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.filechooser.FileFilter;
import javax.swing.tree.TreePath;

import org.jdesktop.swingx.JXTreeTable;
import org.opencompare.ExploreApplication;
import org.opencompare.Snapshot;
import org.opencompare.WithProgress;
import org.opencompare.database.Database;
import org.opencompare.database.DatabaseManagerFactory;
import org.opencompare.database.DescriptionsDatabase;
import org.opencompare.explorable.Explorable;
import org.opencompare.explore.ExplorationException;
import org.opencompare.ui.model.ConflictTreeTableModel;
import org.opencompare.ui.model.DescriptionTreeTableModel;
import org.opencompare.ui.model.EmptyTreeTableModel;
import org.opencompare.ui.model.ExplorableTreeTableModel;
import org.opencompare.ui.model.SnapshotTableDataModel;
import org.opencompare.ui.model.SnapshotTreeTableModel;

public class MainWindow extends javax.swing.JFrame implements WithProgress {

    private static final long serialVersionUID = 1L;
    private static final FileFilter SNAPSHOT_FILE_FILTER = new FileFilter() {

        public boolean accept(File f) {
            return f.isDirectory() || f.getName().endsWith(".snapshot");
        }

        public String getDescription() {
            return "Snapshot (*.snapshot)";
        }
    };

    public MainWindow() {
        initComponents();
        refreshSnapshotList();
        refreshButtons();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        tabs = new javax.swing.JTabbedPane();
        scrollPane = new javax.swing.JScrollPane();
        snapshotsTable = new javax.swing.JTable();
        toolBar = new javax.swing.JToolBar();
        buttonNew = new javax.swing.JButton();
        buttonCompare = new javax.swing.JButton();
        buttonView = new javax.swing.JButton();
        buttonClose = new javax.swing.JButton();
        separator2 = new javax.swing.JToolBar.Separator();
        buttonImport = new javax.swing.JButton();
        buttonExport = new javax.swing.JButton();
        separator3 = new javax.swing.JToolBar.Separator();
        buttonDelete = new javax.swing.JButton();
        buttonRefresh = new javax.swing.JButton();
        separator6 = new javax.swing.JToolBar.Separator();
        buttonFilter = new javax.swing.JButton();
        menuBar = new javax.swing.JMenuBar();
        menuFile = new javax.swing.JMenu();
        menuNew = new javax.swing.JMenuItem();
        menuCompare = new javax.swing.JMenuItem();
        menuView = new javax.swing.JMenuItem();
        menuClose = new javax.swing.JMenuItem();
        separator4 = new javax.swing.JPopupMenu.Separator();
        menuDelete = new javax.swing.JMenuItem();
        menuRefresh = new javax.swing.JMenuItem();
        separator5 = new javax.swing.JPopupMenu.Separator();
        menuFilter = new javax.swing.JMenuItem();
        separator7 = new javax.swing.JPopupMenu.Separator();
        menuImport = new javax.swing.JMenuItem();
        menuExport = new javax.swing.JMenuItem();
        separator1 = new javax.swing.JPopupMenu.Separator();
        menuExit = new javax.swing.JMenuItem();
        menuHelp = new javax.swing.JMenu();
        menuAbout = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Open Compare");
        setLocationByPlatform(true);

        tabs.setTabPlacement(javax.swing.JTabbedPane.BOTTOM);
        tabs.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                tabsStateChanged(evt);
            }
        });

        snapshotsTable.setModel(new SnapshotTableDataModel());
        snapshotsTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        scrollPane.setViewportView(snapshotsTable);

        tabs.addTab("Snapshots", scrollPane);

        toolBar.setRollover(true);

        buttonNew.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/opencompare/ui/images/new.gif"))); // NOI18N
        buttonNew.setText("New...");
        buttonNew.setFocusable(false);
        buttonNew.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        buttonNew.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        buttonNew.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonNewActionPerformed(evt);
            }
        });
        toolBar.add(buttonNew);

        buttonCompare.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/opencompare/ui/images/compare.gif"))); // NOI18N
        buttonCompare.setText("Compare...");
        buttonCompare.setFocusable(false);
        buttonCompare.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        buttonCompare.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        buttonCompare.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonCompareActionPerformed(evt);
            }
        });
        toolBar.add(buttonCompare);

        buttonView.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/opencompare/ui/images/view.gif"))); // NOI18N
        buttonView.setText("View");
        buttonView.setFocusable(false);
        buttonView.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        buttonView.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        buttonView.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonViewActionPerformed(evt);
            }
        });
        toolBar.add(buttonView);

        buttonClose.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/opencompare/ui/images/close.gif"))); // NOI18N
        buttonClose.setText("Close");
        buttonClose.setFocusable(false);
        buttonClose.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        buttonClose.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        buttonClose.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonCloseActionPerformed(evt);
            }
        });
        toolBar.add(buttonClose);
        toolBar.add(separator2);

        buttonImport.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/opencompare/ui/images/import.gif"))); // NOI18N
        buttonImport.setText("Import...");
        buttonImport.setFocusable(false);
        buttonImport.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        buttonImport.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        buttonImport.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonImportActionPerformed(evt);
            }
        });
        toolBar.add(buttonImport);

        buttonExport.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/opencompare/ui/images/export.gif"))); // NOI18N
        buttonExport.setText("Export...");
        buttonExport.setFocusable(false);
        buttonExport.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        buttonExport.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        buttonExport.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonExportActionPerformed(evt);
            }
        });
        toolBar.add(buttonExport);
        toolBar.add(separator3);

        buttonDelete.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/opencompare/ui/images/delete.gif"))); // NOI18N
        buttonDelete.setText("Delete");
        buttonDelete.setFocusable(false);
        buttonDelete.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        buttonDelete.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        buttonDelete.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonDeleteActionPerformed(evt);
            }
        });
        toolBar.add(buttonDelete);

        buttonRefresh.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/opencompare/ui/images/refresh.gif"))); // NOI18N
        buttonRefresh.setText("Refresh");
        buttonRefresh.setFocusable(false);
        buttonRefresh.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        buttonRefresh.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        buttonRefresh.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonRefreshActionPerformed(evt);
            }
        });
        toolBar.add(buttonRefresh);
        toolBar.add(separator6);

        buttonFilter.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/opencompare/ui/images/filter.gif"))); // NOI18N
        buttonFilter.setText("Filter...");
        buttonFilter.setEnabled(false);
        buttonFilter.setFocusable(false);
        buttonFilter.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        buttonFilter.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        buttonFilter.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buttonFilterActionPerformed(evt);
            }
        });
        toolBar.add(buttonFilter);

        menuFile.setText("File");

        menuNew.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_N, java.awt.event.InputEvent.CTRL_MASK));
        menuNew.setIcon(buttonNew.getIcon());
        menuNew.setText(buttonNew.getText());
        menuNew.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuNewActionPerformed(evt);
            }
        });
        menuFile.add(menuNew);

        menuCompare.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_M, java.awt.event.InputEvent.CTRL_MASK));
        menuCompare.setIcon(buttonCompare.getIcon());
        menuCompare.setText(buttonCompare.getText());
        menuCompare.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuCompareActionPerformed(evt);
            }
        });
        menuFile.add(menuCompare);

        menuView.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F3, 0));
        menuView.setIcon(buttonView.getIcon());
        menuView.setText(buttonView.getText());
        menuView.setEnabled(buttonView.isEnabled());
        menuView.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuViewActionPerformed(evt);
            }
        });
        menuFile.add(menuView);

        menuClose.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ESCAPE, 0));
        menuClose.setIcon(buttonClose.getIcon());
        menuClose.setText(buttonClose.getText());
        menuClose.setEnabled(buttonClose.isEnabled());
        menuClose.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuCloseActionPerformed(evt);
            }
        });
        menuFile.add(menuClose);
        menuFile.add(separator4);

        menuDelete.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_DELETE, 0));
        menuDelete.setIcon(buttonDelete.getIcon());
        menuDelete.setText(buttonDelete.getText());
        menuDelete.setEnabled(buttonDelete.isEnabled());
        menuDelete.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuDeleteActionPerformed(evt);
            }
        });
        menuFile.add(menuDelete);

        menuRefresh.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F5, 0));
        menuRefresh.setIcon(buttonRefresh.getIcon());
        menuRefresh.setText(buttonRefresh.getText());
        menuRefresh.setEnabled(buttonRefresh.isEnabled());
        menuRefresh.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuRefreshActionPerformed(evt);
            }
        });
        menuFile.add(menuRefresh);
        menuFile.add(separator5);

        menuFilter.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F, java.awt.event.InputEvent.CTRL_MASK));
        menuFilter.setIcon(buttonFilter.getIcon());
        menuFilter.setText("Filter...");
        menuFilter.setEnabled(false);
        menuFilter.setText(buttonFilter.getText());
        menuFilter.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuFilterActionPerformed(evt);
            }
        });
        menuFile.add(menuFilter);
        menuFile.add(separator7);

        menuImport.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_I, java.awt.event.InputEvent.CTRL_MASK));
        menuImport.setIcon(buttonImport.getIcon());
        menuImport.setText(buttonImport.getText());
        menuImport.setEnabled(buttonImport.isEnabled());
        menuImport.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuImportActionPerformed(evt);
            }
        });
        menuFile.add(menuImport);

        menuExport.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_E, java.awt.event.InputEvent.CTRL_MASK));
        menuExport.setIcon(buttonExport.getIcon());
        menuExport.setText(buttonExport.getText());
        menuExport.setEnabled(buttonExport.isEnabled());
        menuExport.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuExportActionPerformed(evt);
            }
        });
        menuFile.add(menuExport);
        menuFile.add(separator1);

        menuExit.setText("Exit");
        menuExit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuExitActionPerformed(evt);
            }
        });
        menuFile.add(menuExit);

        menuBar.add(menuFile);

        menuHelp.setText("Help");

        menuAbout.setText("About...");
        menuAbout.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                menuAboutActionPerformed(evt);
            }
        });
        menuHelp.add(menuAbout);

        menuBar.add(menuHelp);

        setJMenuBar(menuBar);

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(toolBar, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .add(tabs, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 1130, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                .add(toolBar, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(tabs, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 551, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private Component createSnapshotTree(Snapshot snapshot) throws ExplorationException {
        DescriptionsDatabase descDb = null;

        if (snapshot.getType() != Snapshot.Type.Descriptions) {
            try {
                descDb = DatabaseManagerFactory.get().newDescriptionsConnection();
            } catch (ExplorationException e) {
            	if (ExploreApplication.ENABLE_EXPERIMENTAL_FUNCTIONALITY) {
	                JOptionPane.showMessageDialog(this, "Warning: descriptions database is not available.", "Warning", JOptionPane.WARNING_MESSAGE);
	                // TODO: Ask to download and import complete descriptions snapshot
            	}
            }
        }

        final Database database = DatabaseManagerFactory.get().newConnection(snapshot);

        ExplorableTreeTableModel model;
        if (snapshot.getType() == Snapshot.Type.Conflicts) {
            model = new ConflictTreeTableModel(database, descDb);
        } else if (snapshot.getType() == Snapshot.Type.Snapshot) {
            model = new SnapshotTreeTableModel(database, descDb);
        } else if (snapshot.getType() == Snapshot.Type.Descriptions) {
            model = new DescriptionTreeTableModel(database);
        } else {
            throw new ExplorationException("Trying to open unsupported type of snapshot: " + snapshot.getType());
        }

        final Frame frame = this;
        final JXTreeTable treeTable = new JXTreeTable();
        treeTable.setTreeTableModel(model);

        JScrollPane treeTableScrollPane = new JScrollPane();
        treeTableScrollPane.setViewportView(treeTable);
        treeTableScrollPane.setName(snapshot.getType().toString() + ": " + snapshot.getName());

        final MainWindow thiz = this;

        treeTable.addMouseListener(new MouseAdapter() {
                public void mousePressed(MouseEvent me) {
                    if (me.getClickCount() == 2) {
                        int sel = treeTable.getSelectedRow();
                        if (sel >= 0) {
                            TreePath tp = treeTable.getTreeSelectionModel().getSelectionPath();
                            Object o = tp.getLastPathComponent();
                            if (o instanceof Explorable) {
                                Explorable e = (Explorable) o;
                                try {
                                    DetailsDialog dlg = new DetailsDialog(frame, false, e, database.getFullId(e));
                                    dlg.setVisible(true);
                                } catch (ExplorationException ex) {
                                    ex.printStackTrace();
                                    JOptionPane.showMessageDialog(
                                            thiz,
                                            "Unable to display the details: " + ex.getLocalizedMessage(),
                                            "Error",
                                            JOptionPane.ERROR_MESSAGE
                                        );
                                }
                            }
                        }
                    }
                }
            });

        return treeTableScrollPane;
    }

    private void buttonViewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonViewActionPerformed
        int[] selected = snapshotsTable.getSelectedRows();
        if (selected.length > 0) {
            SnapshotTableDataModel model = (SnapshotTableDataModel) snapshotsTable.getModel();
            for (int i : selected) {
                viewSnapshot(model.get(i));
            }
        } else {
            JOptionPane.showMessageDialog(this, "Please select a snapshot", "Error", JOptionPane.ERROR_MESSAGE);
        }
    }//GEN-LAST:event_buttonViewActionPerformed

    public void refreshSnapshotList() {
        SnapshotTableDataModel model = (SnapshotTableDataModel) snapshotsTable.getModel();
        model.refresh();
    }

    public void viewSnapshot(Snapshot snapshot) {
        try {
            Component tree = createSnapshotTree(snapshot);
            int index = tabs.getTabCount();
            tabs.insertTab(tree.getName(), null, tree, null, index);
            tabs.setSelectedIndex(index);
            refreshButtons();
        } catch (ExplorationException ex) {
            JOptionPane.showMessageDialog(this, "Unable to view snapshot " + snapshot, "Error", JOptionPane.ERROR_MESSAGE);
        }
    }

    private void buttonImportActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonImportActionPerformed
        JFileChooser dlg = new JFileChooser();
        dlg.setDialogTitle("Import snapshot");
        dlg.setMultiSelectionEnabled(false);
        dlg.setFileFilter(SNAPSHOT_FILE_FILTER);

        if (dlg.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
        	DatabaseManagerFactory.get().importSnapshot(
                    dlg.getSelectedFile(),
                    new ProgressDialog(this, "Importing snapshot", null, this)
                );
        }
    }//GEN-LAST:event_buttonImportActionPerformed

    private void buttonExportActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonExportActionPerformed
        Snapshot snapshot = getCurrentSnapshot();
        if (snapshot != null) {

            JFileChooser dlg = new JFileChooser();
            dlg.setDialogTitle("Export snapshot");
            dlg.setMultiSelectionEnabled(false);
            dlg.setFileFilter(SNAPSHOT_FILE_FILTER);

            if (dlg.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {

                // Modify filename if necessary
                File out = dlg.getSelectedFile();
                if (dlg.getFileFilter() == SNAPSHOT_FILE_FILTER) {
                    if (!out.getName().endsWith(".snapshot")) {
                        out = new File(out.getAbsolutePath() + ".snapshot");
                    }
                }

                DatabaseManagerFactory.get().exportSnapshot(
                        snapshot,
                        out,
                        new ProgressDialog(null, "Exporting snapshot", null, this)
                    );
            }
        }
    }//GEN-LAST:event_buttonExportActionPerformed

    /**
     * This method returns currently selected snapshot. If we are on the
     * Snapshots tab, it looks at the selected snapshot. If there's zero or more
     * than one selected snapshots, it will display the error message and return
     * null. If we are on one of the snapshots tabs, it will return the
     * corresponding snapshot.
     */
    private Snapshot getCurrentSnapshot() {
        int tab = tabs.getSelectedIndex();

        if (tab == 0) {
            int[] selected = snapshotsTable.getSelectedRows();
            if (selected.length == 1) {
                SnapshotTableDataModel model = (SnapshotTableDataModel) snapshotsTable.getModel();
                return model.get(selected[0]);
            } else {
                JOptionPane.showMessageDialog(this, "Please select one snapshot", "Error", JOptionPane.ERROR_MESSAGE);
                return null;
            }
        } else {
            return getTabModel(tab).getDatabase().getSnapshot();
        }
    }

    private ExplorableTreeTableModel getTabModel(int tab) {
        if (tab == 0) {
            return null;
        } else {
            return (ExplorableTreeTableModel) getTreeTable(tab).getTreeTableModel();
        }
    }

    private JXTreeTable getTreeTable(int tab) {
        if (tab == 0) {
            return null;
        } else {
            JScrollPane sp = (JScrollPane) tabs.getComponentAt(tab);
            return (JXTreeTable) sp.getViewport().getView();
        }
    }

    private void buttonDeleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonDeleteActionPerformed
        Snapshot snapshot = getCurrentSnapshot();
        if (snapshot != null) {
            if (JOptionPane.showConfirmDialog(this, "Are you sure you want to delete the snapshot? This action cannot be undone.", "Confirmation", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
                closeAllTabsWithSnapshot(snapshot);
                snapshot.delete();
                refreshSnapshotList();
            }
        }
    }//GEN-LAST:event_buttonDeleteActionPerformed

    private void closeAllTabsWithSnapshot(Snapshot snapshot) {
        boolean closedSomething;
        do {
            closedSomething = false;
            for (int i = 1; i < tabs.getTabCount(); ++i) {
                ExplorableTreeTableModel model = getTabModel(i);
                if (model.getDatabase().getSnapshot().equals(snapshot)) {
                    closeTab(i);
                    closedSomething = true;
                    break;
                }
            }
        } while (closedSomething);
    }

    private void buttonRefreshActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonRefreshActionPerformed
        refreshSnapshotList();
    }//GEN-LAST:event_buttonRefreshActionPerformed

    private void menuViewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuViewActionPerformed
        buttonViewActionPerformed(evt);
    }//GEN-LAST:event_menuViewActionPerformed

    private void menuImportActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuImportActionPerformed
        buttonImportActionPerformed(evt);
    }//GEN-LAST:event_menuImportActionPerformed

    private void menuExportActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuExportActionPerformed
        buttonExportActionPerformed(evt);
    }//GEN-LAST:event_menuExportActionPerformed

    private void menuDeleteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuDeleteActionPerformed
        buttonDeleteActionPerformed(evt);
    }//GEN-LAST:event_menuDeleteActionPerformed

    private void menuRefreshActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuRefreshActionPerformed
        buttonRefreshActionPerformed(evt);
    }//GEN-LAST:event_menuRefreshActionPerformed

    private void buttonCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonCloseActionPerformed
        closeTab(tabs.getSelectedIndex());
    }//GEN-LAST:event_buttonCloseActionPerformed

    private void closeTab(int tab) {
        ExplorableTreeTableModel model = getTabModel(tab);
        try {
            model.close();
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(this, "There was an error closing database connection", "Warning", JOptionPane.WARNING_MESSAGE);
        }
        tabs.remove(tab);
        refreshButtons();
    }

    private void refreshButtons() {
        int tab = tabs.getSelectedIndex();

        buttonClose.setEnabled(tab != 0);
        buttonView.setEnabled(tab == 0);
        buttonRefresh.setEnabled(tab == 0);
        buttonFilter.setEnabled(tab != 0 && getTabModel(tab).getDatabase().getSnapshot().getType() == Snapshot.Type.Conflicts);

        menuClose.setEnabled(buttonClose.isEnabled());
        menuView.setEnabled(buttonView.isEnabled());
        menuRefresh.setEnabled(buttonRefresh.isEnabled());
        menuFilter.setEnabled(buttonFilter.isEnabled());
    }

    private void menuExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuExitActionPerformed
        System.exit(0);
    }//GEN-LAST:event_menuExitActionPerformed

    private void menuCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuCloseActionPerformed
        buttonCloseActionPerformed(evt);
    }//GEN-LAST:event_menuCloseActionPerformed

    private void tabsStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_tabsStateChanged
        refreshButtons();
    }//GEN-LAST:event_tabsStateChanged

    private void buttonNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonNewActionPerformed
        CreateSnapshotDialog wizard = new CreateSnapshotDialog(this, true);
        wizard.setVisible(true);
    }//GEN-LAST:event_buttonNewActionPerformed

    private void buttonCompareActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonCompareActionPerformed
        CompareSnapshotsDialog wizard = new CompareSnapshotsDialog(this, true);
        wizard.setVisible(true);
    }//GEN-LAST:event_buttonCompareActionPerformed

    private void menuAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuAboutActionPerformed
        new AboutDialog(this, true).setVisible(true);
    }//GEN-LAST:event_menuAboutActionPerformed

    private void menuNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuNewActionPerformed
        buttonNewActionPerformed(evt);
    }//GEN-LAST:event_menuNewActionPerformed

    private void menuCompareActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuCompareActionPerformed
        buttonCompareActionPerformed(evt);
    }//GEN-LAST:event_menuCompareActionPerformed

    private void buttonFilterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonFilterActionPerformed
        // We assume there's a conflict snapshot currently selected, otherwise this button won't be available
        JXTreeTable treeTable = getTreeTable(tabs.getSelectedIndex());
        ConflictTreeTableModel model = (ConflictTreeTableModel) treeTable.getTreeTableModel();

        FilterDialog fd = new FilterDialog(this, true, model.getFilter());
        fd.setVisible(true);

        if (fd.isUserConfirmed()) {
            model.setFilter(fd.isDisplayIdentical());
            treeTable.setTreeTableModel(new EmptyTreeTableModel());
            treeTable.setTreeTableModel(model);
        }
    }//GEN-LAST:event_buttonFilterActionPerformed

    private void menuFilterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuFilterActionPerformed
        buttonFilterActionPerformed(evt);
    }//GEN-LAST:event_menuFilterActionPerformed

    public static void main(String args[]) {
        /*
         * Set the Nimbus look and feel
         */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /*
         * If Nimbus (introduced in Java SE 6) is not available, stay with the
         * default look and feel. For details see
         * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(MainWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(MainWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(MainWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(MainWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /*
         * Create and display the form
         */
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new MainWindow().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton buttonClose;
    private javax.swing.JButton buttonCompare;
    private javax.swing.JButton buttonDelete;
    private javax.swing.JButton buttonExport;
    private javax.swing.JButton buttonFilter;
    private javax.swing.JButton buttonImport;
    private javax.swing.JButton buttonNew;
    private javax.swing.JButton buttonRefresh;
    private javax.swing.JButton buttonView;
    private javax.swing.JMenuItem menuAbout;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JMenuItem menuClose;
    private javax.swing.JMenuItem menuCompare;
    private javax.swing.JMenuItem menuDelete;
    private javax.swing.JMenuItem menuExit;
    private javax.swing.JMenuItem menuExport;
    private javax.swing.JMenu menuFile;
    private javax.swing.JMenuItem menuFilter;
    private javax.swing.JMenu menuHelp;
    private javax.swing.JMenuItem menuImport;
    private javax.swing.JMenuItem menuNew;
    private javax.swing.JMenuItem menuRefresh;
    private javax.swing.JMenuItem menuView;
    private javax.swing.JScrollPane scrollPane;
    private javax.swing.JPopupMenu.Separator separator1;
    private javax.swing.JToolBar.Separator separator2;
    private javax.swing.JToolBar.Separator separator3;
    private javax.swing.JPopupMenu.Separator separator4;
    private javax.swing.JPopupMenu.Separator separator5;
    private javax.swing.JToolBar.Separator separator6;
    private javax.swing.JPopupMenu.Separator separator7;
    private javax.swing.JTable snapshotsTable;
    private javax.swing.JTabbedPane tabs;
    private javax.swing.JToolBar toolBar;
    // End of variables declaration//GEN-END:variables

    public void start() {
        // Ignore
    }

    public void complete(boolean success) {
        refreshSnapshotList();
    }

    public void setMaximum(int max) {
        // Ignore
    }

    public void setValue(int value) {
        // Ignore
    }

}

redpajama_set_name: RedPajamaGithub


text:
namespace ash {

namespace device_sync {

namespace {

// Strings used as DictionaryValue keys.
const char kInstanceIdDictKey[] = "instance_id";
const char kDeviceNameDictKey[] = "device_name";
const char kLastUpdateTimeDictKey[] = "last_update_time";
const char kDeviceBetterTogetherPublicKeyDictKey[] =
    "device_better_together_public_key";
const char kBetterTogetherDeviceMetadataDictKey[] =
    "better_together_device_metadata";
const char kFeatureStatesDictKey[] = "feature_states";

absl::optional<
    std::map<multidevice::SoftwareFeature, multidevice::SoftwareFeatureState>>
FeatureStatesFromDictionary(const base::Value* dict) {
  if (!dict || !dict->is_dict())
    return absl::nullopt;

  std::map<multidevice::SoftwareFeature, multidevice::SoftwareFeatureState>
      feature_states;
  for (const auto feature_state_pair : dict->DictItems()) {
    int feature;
    if (!base::StringToInt(feature_state_pair.first, &feature) ||
        !feature_state_pair.second.is_int()) {
      return absl::nullopt;
    }

    feature_states[static_cast<multidevice::SoftwareFeature>(feature)] =
        static_cast<multidevice::SoftwareFeatureState>(
            feature_state_pair.second.GetInt());
  }

  return feature_states;
}

base::Value FeatureStatesToDictionary(
    const std::map<multidevice::SoftwareFeature,
                   multidevice::SoftwareFeatureState>& feature_states) {
  base::Value dict(base::Value::Type::DICTIONARY);
  for (const auto& feature_state_pair : feature_states) {
    dict.SetIntKey(
        base::NumberToString(static_cast<int>(feature_state_pair.first)),
        static_cast<int>(feature_state_pair.second));
  }

  return dict;
}

base::Value FeatureStatesToReadableDictionary(
    const std::map<multidevice::SoftwareFeature,
                   multidevice::SoftwareFeatureState>& feature_states) {
  base::Value dict(base::Value::Type::DICTIONARY);
  for (const auto& feature_state_pair : feature_states) {
    std::stringstream feature_ss;
    feature_ss << feature_state_pair.first;
    std::stringstream feature_state_ss;
    feature_state_ss << feature_state_pair.second;
    dict.SetStringKey(feature_ss.str(), feature_state_ss.str());
  }

  return dict;
}

}  // namespace

// static
absl::optional<CryptAuthDevice> CryptAuthDevice::FromDictionary(
    const base::Value& dict) {
  if (!dict.is_dict())
    return absl::nullopt;

  absl::optional<std::string> instance_id =
      util::DecodeFromValueString(dict.FindKey(kInstanceIdDictKey));
  if (!instance_id || instance_id->empty())
    return absl::nullopt;

  absl::optional<std::string> device_name =
      util::DecodeFromValueString(dict.FindKey(kDeviceNameDictKey));
  if (!device_name || device_name->empty())
    return absl::nullopt;

  absl::optional<std::string> device_better_together_public_key =
      util::DecodeFromValueString(
          dict.FindKey(kDeviceBetterTogetherPublicKeyDictKey));
  if (!device_better_together_public_key ||
      device_better_together_public_key->empty()) {
    return absl::nullopt;
  }

  absl::optional<base::Time> last_update_time =
      ::base::ValueToTime(dict.FindKey(kLastUpdateTimeDictKey));
  if (!last_update_time)
    return absl::nullopt;

  absl::optional<cryptauthv2::BetterTogetherDeviceMetadata>
      better_together_device_metadata;
  const base::Value* metadata_value =
      dict.FindKey(kBetterTogetherDeviceMetadataDictKey);
  if (metadata_value) {
    better_together_device_metadata = util::DecodeProtoMessageFromValueString<
        cryptauthv2::BetterTogetherDeviceMetadata>(metadata_value);
    if (!better_together_device_metadata)
      return absl::nullopt;
  }

  absl::optional<
      std::map<multidevice::SoftwareFeature, multidevice::SoftwareFeatureState>>
      feature_states =
          FeatureStatesFromDictionary(dict.FindDictKey(kFeatureStatesDictKey));
  if (!feature_states)
    return absl::nullopt;

  return CryptAuthDevice(*instance_id, *device_name,
                         *device_better_together_public_key, *last_update_time,
                         better_together_device_metadata, *feature_states);
}

CryptAuthDevice::CryptAuthDevice(const std::string& instance_id)
    : instance_id_(instance_id) {
  DCHECK(!instance_id.empty());
}

CryptAuthDevice::CryptAuthDevice(
    const std::string& instance_id,
    const std::string& device_name,
    const std::string& device_better_together_public_key,
    const base::Time& last_update_time,
    const absl::optional<cryptauthv2::BetterTogetherDeviceMetadata>&
        better_together_device_metadata,
    const std::map<multidevice::SoftwareFeature,
                   multidevice::SoftwareFeatureState>& feature_states)
    : device_name(device_name),
      device_better_together_public_key(device_better_together_public_key),
      last_update_time(last_update_time),
      better_together_device_metadata(better_together_device_metadata),
      feature_states(feature_states),
      instance_id_(instance_id) {
  DCHECK(!instance_id.empty());
}

CryptAuthDevice::CryptAuthDevice(const CryptAuthDevice&) = default;

CryptAuthDevice::~CryptAuthDevice() = default;

base::Value CryptAuthDevice::AsDictionary() const {
  base::Value dict(base::Value::Type::DICTIONARY);
  dict.SetKey(kInstanceIdDictKey, util::EncodeAsValueString(instance_id_));
  dict.SetKey(kDeviceNameDictKey, util::EncodeAsValueString(device_name));
  dict.SetKey(kDeviceBetterTogetherPublicKeyDictKey,
              util::EncodeAsValueString(device_better_together_public_key));
  dict.SetKey(kLastUpdateTimeDictKey, ::base::TimeToValue(last_update_time));
  dict.SetKey(kFeatureStatesDictKey, FeatureStatesToDictionary(feature_states));
  if (better_together_device_metadata) {
    dict.SetKey(kBetterTogetherDeviceMetadataDictKey,
                util::EncodeProtoMessageAsValueString(
                    &better_together_device_metadata.value()));
  }

  return dict;
}

base::Value CryptAuthDevice::AsReadableDictionary() const {
  base::Value dict(base::Value::Type::DICTIONARY);
  dict.SetStringKey("Instance ID", instance_id_);
  dict.SetStringKey("Device name", device_name);
  dict.SetStringKey("DeviceSync:BetterTogether device public key",
                    cryptauthv2::TruncateStringForLogs(util::EncodeAsString(
                        device_better_together_public_key)));
  dict.SetKey("Feature states",
              FeatureStatesToReadableDictionary(feature_states));
  dict.SetKey(
      "BetterTogether device metadata",
      (better_together_device_metadata
           ? cryptauthv2::BetterTogetherDeviceMetadataToReadableDictionary(
                 *better_together_device_metadata)
           : base::Value("[No decrypted metadata]")));
  return dict;
}

bool CryptAuthDevice::operator==(const CryptAuthDevice& other) const {
  bool does_metadata_match =
      (!better_together_device_metadata &&
       !other.better_together_device_metadata) ||
      (better_together_device_metadata.has_value() &&
       other.better_together_device_metadata.has_value() &&
       better_together_device_metadata->SerializeAsString() ==
           other.better_together_device_metadata->SerializeAsString());

  return does_metadata_match && instance_id_ == other.instance_id_ &&
         device_name == other.device_name &&
         device_better_together_public_key ==
             other.device_better_together_public_key &&
         last_update_time == other.last_update_time &&
         feature_states == other.feature_states;
}

bool CryptAuthDevice::operator!=(const CryptAuthDevice& other) const {
  return !(*this == other);
}

std::ostream& operator<<(std::ostream& stream, const CryptAuthDevice& device) {
  stream << device.AsReadableDictionary();
  return stream;
}

}  // namespace device_sync

}  // namespace ash


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<title>org.jsimpledb.parse Class Hierarchy (Java Class Library API)</title>
<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">

JavaScript is disabled on your browser.

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev

Next

Frames

No Frames

All Classes

Hierarchy For Package org.jsimpledb.parse

Package Hierarchies:

All Packages

Class Hierarchy

java.lang.Object

org.jsimpledb.parse.CompositeIndexParser (implements org.jsimpledb.parse.Parser<T>)

org.jsimpledb.parse.EnumNameParser<T> (implements org.jsimpledb.parse.Parser<T>)

org.jsimpledb.parse.FieldTypeParser<T> (implements org.jsimpledb.parse.Parser<T>)

org.jsimpledb.parse.IndexedFieldParser (implements org.jsimpledb.parse.Parser<T>)

org.jsimpledb.parse.IndexedFieldParser.Result

org.jsimpledb.parse.ObjIdParser (implements org.jsimpledb.parse.Parser<T>)

org.jsimpledb.parse.ObjInfo

org.jsimpledb.parse.ObjTypeParser (implements org.jsimpledb.parse.Parser<T>)

org.jsimpledb.parse.ParseContext (implements java.lang.Cloneable)

org.jsimpledb.parse.ParseUtil

org.jsimpledb.parse.ParseUtil.HasNamePredicate (implements com.google.common.base.Predicate<T>)

org.jsimpledb.Session

org.jsimpledb.parse.ParseSession

org.jsimpledb.parse.SpaceParser

java.lang.Throwable (implements java.io.Serializable)

java.lang.Exception

java.lang.RuntimeException

org.jsimpledb.parse.ParseException

org.jsimpledb.parse.WordParser (implements org.jsimpledb.parse.Parser<T>)

Interface Hierarchy

org.jsimpledb.parse.Parser<T>

org.jsimpledb.parse.ParseSession.Action

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev

Next

Frames

No Frames

All Classes


text:
layout: default
---

Lesson 4: Exploratory Data Analysis With data.table
===========

Segment 1: R Scripts
-----------

In these lessons so far you've learned a lot about the statistical programming language R: you've learned how to set variables and work with data structures, to create informative visualizations using ggplot2, and how to perform rigorous statistical tests. But datasets from the real world aren't so simple: they might contain dozens of variables across tens of thousands of observations. You might need to filter them based on quality considerations, and they might be spread across multiple datasets, leaving you to combine them together yourself. I'm David Robinson, and in this lesson we're going to tie all your R skills together, by learning how to perform exploratory data analysis using the powerful data.table package. As an example, we'll be analyzing a dataset of historical baseball statistics, learning how to preprocess and filter it, how to combine multiple datasets together, and how to answer interesting questions interactively with your data.

This lesson will assume basic familiarity with R, especially vectors and data frames, with RStudio, and with the ggplot2 package for visualization.

One of the essential functions of computers is to take repetitive, dull tasks and automate them, so they can be easily be performed as many times as you need. Part of being a good programmer is sticking to this philosophy.

So far we've been working in the interactive R terminal. This is useful for writing a line of code quickly and seeing the result.

But most of your analyses will take multiple lines of code and they'll have to be run all in the same order, and it's impractical to have to type them all in sequence in an interactive window. So let's instead write an R script, which will contain a series of commands that you want to run in order. In RStudio, Go to File->New File->New R Script, or you can do CMD+SHIFT+N, to create a new R script. You'll see it pops up above your command prompt. Write a couple lines of R. For example, let's define two variables:

Now save your new script. First you have to choose a working directory, which you can do with "More->Set as Working Directory" in the file manager in RStudio. Then save your script, which you can do with CMD+S or with the floppy disk icon here. Let's save it as `script.R` in our working directory. Now we can run this script- that is, all our commands in the script all at once- by clicking "Source" at the top of the script. Notice that a command pops up in your interactive terminal, something like

That means it ran all the commands in your script in a row. You can see this by checking the values of `x` and `y`:

So even though you didn't see the commands in the interactive terminal, they did run when you hit Source.

Incidentally, there's a keyboard shortcut for sourcing a current file as well: you can do CMD+SHIFT+S.

Now what if we want some output to our script besides just setting a few variables? Normally we'd be able to view the contents of a variable just by typing that variable by itself. For instance:

However, try putting the line `y` by itself in your script, save, and source it. Notice there was no output. That's because when you run outside of the interactive terminal, values don't print unless you explicitly tell them to do so. You do that with the print function. Change your line in the file to `print(y)`, then save and source.

*Now* we can see the output in your interactive window. Remember that: when you're running inside a script, if you want to see an output, you have to actually print it.

Importantly, the same is true of a ggplot2 plot. Let's create a basic ggplot:

As soon as we hit return on this line, we created a scatterplot. However, let's put the same lines of code into our script. Then we clear the current plot by hitting Clear All, and hit Source.

Notice that no plot showed up. The reason is that when it's in a file, a ggplot, just like a regular variable, needs to be printed to show up. You do that with:

Finally, there's a useful shortcut for running one line at a time in a script. Put your cursor on a particular line of code, then hit CMD+RETURN in Macs, or CONTROL+ENTER on Windows, you'll run just that line of code in your interactive terminal. This means you don't have to select a line and copy and paste it into your terminal. This is useful for if you want to run a single line of code in your script, but don't want to go through the time of rerunning the whole file.

R scripts can be as long as you like: yours may end up being hundreds or even thousands of lines of code- and they're the only practical way to organize a complicated analysis productively.

Segment 2: Reading Data
--------------

So far we've been working with built-in datasets in R. For example, remember that we can load the `mtcars` dataset by doing

R comes with dozens of useful datasets like this, and they're great for learning and practicing. But of course, whatever data you're actually interested in, chances are it's probably not already built into R. So how can you read your own data into R?

Let's start by downloading some data and reading it in. We're going to be working with a dataset about baseball: specifically the 2013 version of Sean Lahman's Baseball Archive. The statistical analysis of baseball is called sabermetrics, and it has a rich and fascinating history: this dataset can be used to explore lots of extraordinary trends. Don't worry if you're not a fan of baseball, or even if you know nothing about it: we're just using it as an example of data manipulation. I'll explain everything as we go along, and you'll have just as much fun as anyone.

So the URL for this file is [http://dgrtwo.github.io/pages/lahman/Salaries.csv](http://dgrtwo.github.io/pages/lahman/Salaries.csv). Take this URL and put it into your favorite web browser. At this point you can see the comma separated values in the dataset. Let's save it to our computer, particularly putting it into your current working directory. Make sure it's saved as a CSV file. We should now have the Salaries.csv file in your file manager in RStudio.

Let's look at the contents of this CSV file a little more closely. This is called CSV, or comma-separated value, format. It contains one header row, and then a series of lines made up of multiple fields separated by commas. This is one of the most common formats data is shared in. For instance, if you have an Excel spreadsheet, note that you can save it into CSV format.

You can read a CSV file into R easily with the `read.csv` function:

This read in the CSV file as a data frame. You can see this by doing

This data is organized into rows: one row per player per year. You can see a column for the year, for the ID of the player, and for the salary in US dollars. You can also see the team that the player was playing on, and the league, either the American League (`AL`) or National League (`NL`) that the team plays in.

I had you download the file just so we could look at it, but note that you don't actually have to download it at all. R can read a CSV file directly from the internet, if you give it the URL. Take that URL we had and put it into `read.csv` directly:

This downloads the file, reads it in, and saves it into the same data.frame.

Now, this was the best way to read this standard CSV file. But what if you didn't have a header row? Or what if your file were separated by spaces, or by tabs, instead of by commas? Take a look at the help page for `read.csv`:

You can see here that there are multiple ways to use `read.csv` with different defaults and options. For example, if you didn't want to have a header, you could change the header option to `header=FALSE`. If you wanted the fields to be separated by spaces, rather than commas, you could add `sep=" "`. Don't do that in this case.

You can also see that R provides other functions such as `read.table` whose defaults are different (space separation with no header). So by choosing the right function, and the right set of specialized option, you can read almost any kind of row/column organized file.

R can't read everything. But for the majority of cases, if your data was prepared responsibly and you set these simple options correctly, you can use the `read.csv` and `read.table` functions to import whatever data you need.

Segment 3: Introduction to data.table
-------------

Now we have downloaded this data on baseball players' salaries, we're interested in filtering and manipulating it. The salary data is currently held in a data.frame, a data structure built into R. data.frame is powerful, but there's an even more powerful alternative in R that makes data manipulation fast, easy and intuitive. Like ggplot2, it's a third party package, which means it doesn't come built in, and we have to install it. So let's install the `data.table` package You can do that with:

Now, before we learn to use data.table, let's take one last look at salaries the data.frame. If you type

it will print thousands and thousands of lines until it decides to stops. Now, let's convert the data.frame into a data table. First you load the `data.table` package:

Then use the `as.data.table` function to replace `salaries` with a data.table version.

Now, let's print it again:

Notice that it contains the same information, but only shows the first five rows, then ---, then the last five rows, which is generally a more convenient representation. This more compact way of printing a data.table is the first benefit of using the package.

Now, a lot of things work just the same way as they do in a data.frame. You can still access a column with a dollar sign. For instance, let's say you want the `salary` column.

Or to get a single row of a data.table, you can do:

Or you can get a range of rows:

One thing that did work on data frames but doesn't work on data tables is extracting a column based on an index. In a data.frame, you could extract the first column by putting the index after the comma:

But that doesn't work in data.table. Instead, you can put the name of the column, *without quotes*, after the comma:

This retrieves the entire vector of that year.

You can also grab multiple columns (for example, just the year and the salary) using `list`:

Now we've created a new data table with just the two columns `yearID` and `salary`.

Now, let's say we want to filter the rows based on one column, which is a common step in data preprocessing. For example, let's say you want to get only the years after 2000. There is an easy way to do this in data.table. We put a condition before the comma:

Now we've created a subset of the data that contains only years 2001 and after. Similarly, if you wanted to get salaries from a specific year, 2010, you could do

There are two leagues in American Major League Baseball: the American League (`AL`), and the National League (`NL`). If we want to filter for just the American League, we can do:

Now I've selected just the American League teams.

Finally, we can combine multiple filtering conditions using the *and* (`&`) or *or* (`|`) operators. For instance, we can filter for all the rows in the American League that were after 1990.

Similarly, we can combine conditions with *or* (`|`). For instance, say we wanted only years before 1990 or after 2010.

We can also sort the data easily, using the order function in the area before the comma:

Now you can see that the pairs of players and years are sorted by salary, with the lower salaries at the top. This gives us an easy way to see the highest and lowest salaries. In case you're wondering, NYA here is the team ID of the New York Yankees: called NYA instead of NYY for historical reasons. We could also sort by year:

What if we want to sort first by year, and *then* breaking ties with salary? We can do that by providing two arguments to the order function:

Now it's organized with 1985 first, and 2013 last, but within each of those years it is organized by salary.

Note that we can perform multiple operations all in a sequence, by saving the intermediate results. For instance, we can first perform a filtering operation and save it as `salaries.filtered`:

Then we can sort it by salary and save it into a new data table, which is now both filtered and sorted.

These operations let us easily explore the data and answer basic questions.

Segment 4: Summarizing Data Within Groups
--------------

In our last segment we learned how to download a dataset on baseball player salaries and turn it into a data table, and then to perform some basic organizations on it like filtering and sorting. Now we're going to learn about a more sophisticated and powerful way of processing the data, namely performing summary operations within groups. This is an important and omnipresent task in data analysis.

Let's look again at our salaries dataset.

Right now we have 24 thousand rows, each with a combination of a year and a player. Now, we can perform some general summaries of this data. For example, we can extract the salary column using a dollar sign ($):

Then we can find the average salary of all players across all years with the mean function:

Similarly, we could find the highest salary across all years with `max`:

or the median:

We can also find the average salary in a given year by filtering the data before we extract the column. This code extracts the salaries only from the year 2000:

We can then find the average salary in the year 2000:

This gives us a good way to ask questions interactively about our data. But what if we want to look for a trend- for example, how baseball player salaries change over time? It would be a huge hassle to repeat this line of code for 1985, 1986, 1987 and so on, and them combine all of those. What we want is a way to perform this summary operation of averaging within each year, for every year in the dataset. It turns out the data.table package makes that easy:

Let's create a new data.table called `summarized.year`, then we subset it using square brackets in a very particular way. Put nothing before the first comma. Now after the second comma, we say we want to take the mean of the salary column- but then we put another comma and `by="yearID"`, which means  we don't want to do it once for the whole dataset- we want to do it within each year. So we're computing the mean salary (`mean(salary)`), within each year (`by="yearID"`).

This message in red is a warning: it's basically complaining that baseball players are paid too much. But you can ignore it, it doesn't have any effect on our results. Let's look at what ended up in `summarized.year`:

We now have two columns: one for year, which we were summarizing by, and one called V1. Every year has its own row, and this V1 was the result of this expression we put between the two commas.

What if we wanted to give it a more useful name, like "Average"? We can do that by changing what we put in our summarizing expression, by placing the `list()` function between the commas.

This means we want to create a column called average that contains the mean salary within each year. (Ignore the warning again). Now you can see that the column is called `Average`, which is more helpful. But our summary operation doesn't have to stop there. We can create two columns at the same time: one for the average, and one for the maximum:

Now you can see that we've created two columns along with the summarizing year: one with average, one with maximum.

We could add other columns as well, showing, for instance, the minimum or standard deviation or the salary within each year. Anything you put in this list will end up being a column.

You can group your summaries by any column in the data, not just the year. For example, you could summarize within each baseball league- those two leagues being the American League and the National League. Again we put a `list()` of the columns we want to create within the commas, but this time put `by="lgID"`.

Now you can see there are only two rows: one for the American League, one for the National League, and we can see the average and maximum salaries within each.

We've already summarized by year, and by league- we could also summarize by team. We would just change `by="lgID"` to `by="teamID"`.

Now we can see one row for each team.

Note that this output is itself a data.table, just like the input was. You can process it or sort it just like you could any other. For example, you could filter it to look only at a particular range of years. Here we look for years after 2000:

Here we get a smaller subset of that summary. Similarly you can sort the output, for instance to find the highest paid and lowest paid teams.

Finally, we can group by more than one column in our analysis. Let's say we want to see the average salary within each year, separately for the two leagues: so we're summarizing by the league and year combination. To do this, we change the by argument to be a vector `c("yearID", "lgID")`.

Notice it has one row for each combination of a year and a league- for example, one for the year 1985 within AL (American League), and one for 1985 NL (National League), and has the average and maximum within each of these. You could go even farther and view the analysis within each team, within each year. Just change the `lgID` to `teamID`:

Now, any of these summaries could be used as the result of an analysis, for example as a table in a presentation or paper. But they also make visualizing trends much easier. For example, let's say we want to examine the trend of how salary changes over time. We could produce a plot of all the points in the original salaries dataset, all 24 thousand combinations of players and years. For that we'll use ggplot2, which we covered in a previous segment:

Perform this on our original dataset `salaries`, putting on the x-axis `yearID` and on the y-axis `salary`.

So in this graph we can see a positive trend in salary over time. However, all we can really see is the range of salaries: within this mass of points it's not possible to tell what the average is for each of these years. If we actually want to see how the average changed over time, we can instead plot the summarized data. We get this from `summarized.year`:

We have the year in one column and the average salary in another. So use that `yearID` as our x-axis and `Average` as our y-axis. Usually when we have one trend we put just a line:

Now we can see the trend of the average over time. This comes directly from the summarized data, where we have the average per year.

We can even go farther- since we have it summarized by year *and* league, we can plot `summarized.year.lg` instead. We still put `yearID` on the x-axis and `Average` on the y, but now we color based on the league ID (`lgID`):

Now we can see two separate lines- one red for the American League, and one green for the National League.

Notice that data.table and ggplot2 have a natural synergy: data table lets you summarize your data to the extent you need to visualize what you want with `ggplot2`. Together they work as two powerful tools for exploratory data analysis.

Segment 5: Merging Data
-------------

Let's take a closer look at the baseball player salary data that we've downloaded and imported into R. You can do that with

Notice that the players are not represented by their actual first and last names- they're represented by some kind of ID. This ID looks pretty unhelpful: why not just put their names in that column?

The first reason is that there are multiple players in history that have the same name, and at that point if you used their names to identify them, it wouldn't be possible to tell them apart in the data. Meanwhile, these IDs are guaranteed to be unique per player. There are other advantages: for example, the player ID is shorter and therefore takes up less storage space- but the uniqueness is the most important. That ID can be used to connect this column to other datasets.

So what do I mean by other datasets? Well, the salary data is just one table within the Lahman baseball dataset. Let's load in a different one, from a slightly different URL. Go back to the line where we read in the salary data, but change `Salary.csv` to `Master.csv`, and save it to a variable called `master`.

Before we do anything else, let's turn this data frame into a data table just like we did with `salaries`:

Let's take a look at the table:

This is a master list of the baseball players based on their ID. Here in the first column you can see the playerIDs that appeared in the salaries data. But you can also see a lot of biographical information, like their birthday and birthplace, their weight and height, the date of their death, and most importantly, their full name. So now in one table (`salaries`) we just have the ID, and in another table (`master`) we have a way of getting from that name to their full biographical information. So, let's take the first name on this list: someone named David Aardsma. We could take this players ID, copy it, and extract just this player's salary:

Based on their ID, we were able to extract the years of their salary. You can see that David Aardsma played in seven years, you can see it rose from 2004 to 2010, before dropping back down again. So this is a way we can get one player's name and team along with his salary each year. But it's very clumsy to have to do it individually for each player. Luckily there's a much easier way to connect these two datasets: we can merge them, using the `merge` function. Let's create a new merged dataset called `merged.salaries`.

The "by" argument defines what column we should use to merge them. In this case, that's what column is shared between them, which is `playerID`.

Notice that we can still see all the data from the `salaries` dataset- the player ID, year, team, league, and salary. But each player's salary in each year- but we've also combined it with their biographical information- like their birthday and place, and most notably their name. So we've combined these two tables based on this common column: we have them all in one place. If you wanted to look for trends in salary- for instance, a connection of salary to a player's height, weight, or birth country- you now have all the information in one data table.

One note, having their first and last names as different columns is useful, but we'd like to combine them together into a new column, of first name-space-last name. One way we can create a new column in a data.table is with the `:=` operator:

This means assign a new column, `name`, and now we can give it a value based on other columns in the dataset. The `paste` function is a useful function in R for combining two vectors of strings to be separated by spaces. If we put `nameFirst` and `nameLast`, because we're within the data.table, that we want to combine those two names into a new name.

You can see that we've added a new column, `name`.

Merging can sometimes be a bit more complicated. For example, let's bring in one more dataset, this one a history of each player's batting statistics for each year. To do that, take the earlier `read.csv` line, change `Master.csv` to `Batting.csv`, and save it into a variable called `batting`:

Then let's turn it into a data.table, just like we did for `master`:

This is the most complex dataset yet. Here, like the salary data, we have one row per player per year, and their team ID and league ID. But we also have many statistics summarizing how well he did at batting that year. For instance, G represents how many games the player played in, AB represents the number of times a player went up to bat (how many chances they had to get a hit), H represents the number of hits, and HR represents the number of home runs he scored (hitting the ball out of the park, which gets a run in just one hit).

Now, let's say we want to combine this data with the salary data- for example so we can see how salary is correlated with performance. First, notice that the salary table and the batting table don't share only one column of player ID: they share four: playerID, teamID, leagueID and yearID. That's because we have multiple batting statistics and salary for each single player. This means we won't just be merging by player: we'll be merging them based on the combination of all four columns.

The way we do that is with the `by` argument to `merged`. Instead of giving just the `playerID` to `by`, we give a vector of the four shared columns.

Now it has all the information that was in the batting dataset, but it also added a column for salary. Another thing to note is that we don't have salary information on every player in every year: in particular, we've lost all information on players before 1985. There is a way we can fix this, by adding the `all.x` option to the `merge` function:

This means "keep everything in the first dataset we're merging," which is `batting` (`all.y` would mean "keep everything in the second dataset"). Notice now that now all rows have information in the `salary` column: some have NA, which means "missing value," or "not applicable." So notice that all the rows where we have salary data get to keep their value, while all the ones that don't get filled in by the missing value NA.

Now we can take this merged dataset and merge it with our biographical data in the master list. Here that would be

Now we see we still have the same batting information, but we also have the biographical information from the master list- for example, each player's real name. We've created one mega-dataset covering all three kinds of information. The Lahman baseball dataset contains a lot more information, including player's fielding statistics, presence in the Hall of Fame, pitchers, managers, and so on, all sharing these same IDs. By merging these datasets in the right way, you can answer very complex and interesting questions.

Segment 6: Exploratory Data Analysis
-------------

So let's wrap up by taking all these tools together on our mega-merged dataset. Just like any other dataset, we can filter and process this. For example, this dataset includes pitchers, who might never go up to bat in a whole season. That could end up skewing our analysis.

An example would be David Aardsma, who in many years never even had a single At Bat (AB is 0). We can start by filtering out all the years in which someone has no At Bats.

Now we can see that all At Bat's are at least 1.

Now, one thing baseball fans like looking for is career records. That means we want to summarize across all the years that a batter played, and find, for example, the total number of home runs each player hit. Recall that we learned to do that with "by". For example:

Here we create one column, `Total.HR`, which we define as the sum of home runs for each player, and we tell it to perform these summaries on each player individually.

Now we can see that we've created a new data.table that contains each player's ID and their total career home runs. But in the process, since the only thing we're summarizing by is the player ID, we lost track of their actual first and last names. There's a simple way around that. First, recall that we can create a new column that combines the players' first and last names using `paste` and `:=`, and let's try the same trick again, this time on `merged.all`:

Now we've added to `merged.all` a `name` column:

Now when we perform this summary, let's do it not just on the player ID, but also on their name:

By summarizing based on these two columns, we can keep both their ID and their real name.

Now, just like any data.table, we can sort it to find out who the top home-run hitters are. For this we use the `order` function:

Baseball fans won't be surprised that at the top we can see Barry Bonds, Hank Aaron, Babe Ruth, and some other legendary baseball hitters. In the same way we can summarize by other statistics, like total number of hits or runs. For instance, here let's add `Total.R` for total number of runs, and `Total.H` for total number of hits.

Now we've saved all that career information into `summarized.batters`.

The more a player gets hits in baseball, the more chance they have to actually score runs. That means it's not surprising that there's a correlation between them. We can take a look at that correlation through ggplot. We'll put total hits (`Total.H`) on the x-axis and total runs (`Total.R`) on the y-axis.

Here we can see a clear correlation between the number of hits a player gets and the number of runs.

So far each of these summaries has been of one statistic: the total number of home runs, or the total number of hits. But some baseball statistics are calculated based on several of a player's statistics. For example, consider the batting average, which is the number of hits a player gets, divided by the number of times he goes up to bat.

So in our batting dataset, for Hank Aaron in 1955, we can see that he had 189 hits out of 602 at-bats. We'd calculate his batting average as

for that year. What if we wanted to compute each player's career batting average? It turns out that's easy with the summary operation. We add a column `BattingAverage` to the summary data.table, which we put as the sum of all hits divided by the sum of all at-bats.

This kind of summary operation thus lets us generate any statistic we're interested in. We could then, for instance, put it into a histogram to find out its distribution:

We can see that they center around about 25%, with a large number of people with close to 0 batting average, which would mostly be pitchers.

In this way you're able to test hypotheses almost as fast as you can think of them. This loop of asking questions about your data and getting answers back is the core of exploratory data analysis.


text:
package db

import (
  "labix.org/v2/mgo"
  "github.com/Sirupsen/logrus"
)

var (
  Session *mgo.Session
  Log *logrus.Logger
)

func DBSession() (*mgo.Session, error) {
  var err error

  Log = logrus.New()

  if Session == nil {
    Session, err = mgo.Dial("localhost")
    if err != nil {
      Log.Fatal("failed to connect mongo:", err)
      return nil, err
    }
  }
  return Session.Copy(), nil
}


text:
layout: news_item
title: 'Frida 4.5 Released'
date: 2015-09-10 19:00:00 +0100
author: oleavr
version: 4.5
categories: [release]
---

Time for another packed release. This time we're bringing a brand new spawn
gating API that lets you catch processes spawned by the system, and tons of
Android improvements and improvements all over the place.

So without further ado, the list of changes:

4.5.0:

- core: add *Process.pageSize* constant
- core: let *Memory.alloc()* allocate raw pages when size >= page size
- core: fix NativeFunction's handling of small return types
- core: fix PC alignment when rewriting BLX instructions
- core: add spawn gating API
- core: implement *get_frontmost_application()* on Android
- core: implement *enumerate_applications()* on Android
- core: add support for spawning Android apps
- core: add support for injecting into arm64 processes on Android
- core: add support for Android M
- core: patch the kernel's live SELinux policy
- core: integrate with SuperSU to work around restrictions on Samsung kernels
- core: work around broken sigsetjmp on Android, and many other Android fixes
- core: fix crash when enumerating modules on Linux
- core: optimize exports enumeration for remote processes on Darwin
- dalvik: port to ART and deprecate *Dalvik* name, now known as *Java*
- java: add *Java.openClassFile()* to allow loading classes at runtime
- java: fixes for array conversions and field setters
- python: add support for the new spawn gating API
- python: allow script source and name to be unicode on Python 2.x also
- python: fix error-propagation in Python 3.x
- python: fix the Linux download URL computation
- node: add support for the new spawn gating API
- node: port to Nan 2.x

4.5.1:

- core: fix `ensure_host_session()` error propagation

Enjoy!


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Boost.Geometry (aka GGL, Generic Geometry Library)</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
<link href="tabs.css" rel="stylesheet" type="text/css">

Main Page

Related Pages

Modules

Namespaces

Classes

Files

Examples

Namespace List

Namespace Members

boost

geometry

detail

Namespaces |
Classes |
Functions

boost::geometry::detail Namespace Reference

Namespaces

 	partition

 	overlay

 	envelope

 	is_simple

 	is_valid

 	de9im

 	turns

 	helper_geometries

Classes

struct  	andoyer_inverse

 	The solution of the inverse problem of geodesics on latlong coordinates, Forsyth-Andoyer-Lambert type approximation with first order terms.  More...

struct  	coordinate_cast< rational< T > >

struct  	result_direct

struct  	result_inverse

struct  	thomas_inverse

 	The solution of the inverse problem of geodesics on latlong coordinates, Forsyth-Andoyer-Lambert type approximation with second order terms.  More...

struct  	unique_types

struct  	variant_or_single

struct  	vincenty_direct

 	The solution of the direct problem of geodesics on latlong coordinates, after Vincenty, 1975.  More...

struct  	vincenty_inverse

 	The solution of the inverse problem of geodesics on latlong coordinates, after Vincenty, 1975.  More...

Functions

template<typename Range , typename Geometry >

Range & 	as_range (Geometry &input)

 	Function getting either the range (ring, linestring) itself or the outer ring (polygon)  More...

template<typename Range , typename Geometry >

Range const & 	as_range (Geometry const &input)

 	Function getting either the range (ring, linestring) itself or the outer ring (polygon), const version.  More...

template<typename Geometry , typename Actor >

void 	for_each_range (Geometry const &geometry, Actor &actor)

Function Documentation

template<typename Range , typename Geometry >

          Range& boost::geometry::detail::as_range
          (
          Geometry &
          input	)

Function getting either the range (ring, linestring) itself or the outer ring (polygon)

Utility to handle polygon's outer ring as a range

template<typename Range , typename Geometry >

          Range const& boost::geometry::detail::as_range
          (
          Geometry const &
          input	)

Function getting either the range (ring, linestring) itself or the outer ring (polygon), const version.

Utility to handle polygon's outer ring as a range

template<typename Geometry , typename Actor >

          void boost::geometry::detail::for_each_range
          (
          Geometry const &
          geometry,

          Actor &
          actor

          )

April 2, 2011

Copyright © 2007-2011 Barend Gehrels, Amsterdam, the Netherlands

Copyright © 2008-2011 Bruno Lalande, Paris, France

Copyright © 2009-2010 Mateusz Loskot, London, UK

<address style="text-align: right;">
Documentation is generated by Doxygen
</address>


text:
function customPopupDialog(message, title, windowHight, okButton, callback, windowWidth) {
    var strDialog = "

" + message + "
";
    var requiredWidth = 750;
    if (windowWidth) {
        requiredWidth = windowWidth;
    }
    var func = function() {
    jQuery("#dcontainer").html(strDialog);
    if (okButton) {
        jQuery("#dialog").dialog({
            close:function() {
                jQuery(this).dialog('destroy').remove();
                jQuery("#dcontainer").empty();
                return false;
            },
            buttons:{
                "OK":function() {
                    if (callback && typeof callback == "function")
                        callback();
                    jQuery(this).dialog("destroy").remove();
                    jQuery("#dcontainer").empty();
                    return false;
                }
            },
            height:windowHight,
            width:requiredWidth,
            minHeight:windowHight,
            minWidth:requiredWidth,
            modal:true
        });
    } else {
        jQuery("#dialog").dialog({
            close:function() {
                jQuery(this).dialog('destroy').remove();
                jQuery("#dcontainer").empty();
                return false;
            },
            height:windowHight,
            width:requiredWidth,
            minHeight:windowHight,
            minWidth:requiredWidth,
            modal:true
        });
    }
    };
    if (!pageLoaded) {
        jQuery(document).ready(func);
    } else {
        func();
    }
};


text:
module Fastlane
  module Actions
    module SharedValues
      ARCHIVE = :ARCHIVE
    end

    class ArchiveAction < Action
      def self.run(params)
        puts 'yes'
      end

      def self.is_supported?(platform)
        true
      end
    end
  end
end


text:
@interface ViewController : UIViewController <UIAccelerometerDelegate> {
	CADisplayLink *displayLink;
	ChipmunkSpace *space;
	FallingButton *fallingButton;
}

@end


text:
import Model from 'ember-data/model';
import {belongsTo, hasMany} from 'ember-data/relationships';
import attr from 'ember-data/attr';

export default Model.extend({

    show: belongsTo('show'),
    showname: attr('string'),
    host: attr('string'),
    date: attr('string'),
    notes: attr('string'),
    complete: attr('boolean', {defaultValue: false}),
    tracks: hasMany('playlistentry', {inverse: 'playlist'})

});