Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,22 @@ Choose **Publications**, select a paper or **Create an entry**, and fill in
the title, year, authors (one per line), venue, paper URL, and publication type.
Add research areas and related datasets where relevant.

Paste the abstract into **Abstract**. Use Markdown for formatting and LaTeX for math.
Full LaTeX documents and custom packages are not supported.
Use the published paper URL when available. Include full papers, not abstract-only
conference, poster, or demo entries.

Paste the original abstract into **Abstract**.
Abstracts use **Markdown**, with **LaTeX equations** :

- Text: `*italics*`, `**bold**`, and `[link text](https://example.org)`.
- Inline equations: `$x^2$` or `\(x^2\)`.
- Separate equations: `$$x^2$$` or `\[x^2\]`.

Use `*text*` for italics, not `\textit{text}` outside an equation.
Full LaTeX documents and custom packages are not supported.
Put extra details in **Additional notes**.

The archive shows 100 papers per page; search covers the entire archive.

### Create or edit a personal page

Save your member profile first, then choose **Personal Pages** and your
Expand Down
10 changes: 10 additions & 0 deletions assets/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -1195,6 +1195,16 @@ a.chip {
}

[data-publication-controls][hidden] { display: none; }

.publication-pagination {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 1rem;
}

[data-publication-results] { scroll-margin-top: 6rem; }
button { cursor: pointer; }
button:disabled { cursor: default; opacity: 0.6; }

Expand Down
184 changes: 140 additions & 44 deletions assets/js/site.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,79 +64,175 @@ document.addEventListener("DOMContentLoaded", () => {
}

const searchInput = document.querySelector("[data-publication-search]");
const cards = Array.from(document.querySelectorAll("[data-publication-card]"));
const emptyState = document.querySelector("[data-publication-empty]");
const filterButtons = Array.from(
document.querySelectorAll("[data-publication-tag]"),
);

if (searchInput) {
const archive = document.querySelector("[data-publication-archive]");
const results = document.querySelector("[data-publication-results]");
const paginations = [...document.querySelectorAll("[data-publication-pagination]")];
const errorState = document.querySelector("[data-publication-error]");
const emptyState = document.querySelector("[data-publication-empty]");
const controls = document.querySelector("[data-publication-controls]");
const researchSelect = document.querySelector("[data-publication-research]");
const resultCount = document.querySelector("[data-publication-count]");
const clearButton = document.querySelector("[data-publication-clear]");
const filterButtons = [...document.querySelectorAll("[data-publication-tag]")];
const normalize = (text) => text.normalize("NFD").replace(/\p{M}/gu, "").replace(/[‘’]/g, "'").toLowerCase();
const searchIndex = cards.map((card) => normalize(card.dataset.search || ""));
const pageSize = 100;
let records;
let indexRequest;
let activeTag = "all";

const applyFilter = (updateURL = true) => {
let currentPage = Number(archive.dataset.publicationPage);
let revision = 0;
let searchTimer;

// The initial page is server-rendered. Fetch the searchable metadata once,
// only when filters (including a shared search URL) are used.
const loadIndex = async () => {
if (!indexRequest) {
indexRequest = fetch(archive.dataset.publicationIndex)
.then((response) => {
if (!response.ok) throw new Error("Publication index unavailable");
return response.json();
})
.then((data) => {
records = data.map((record) => ({ ...record, search: normalize(record.search) }));
return records;
})
.catch((error) => { indexRequest = null; throw error; });
}
return indexRequest;
};
const element = (tag, text, className) => {
const node = document.createElement(tag);
if (text !== undefined) node.textContent = text;
if (className) node.className = className;
return node;
};
const cardFor = (record) => {
const card = element("article", undefined, "list-card publication-card");
card.dataset.publicationCard = "";
const title = element("h2");
const link = element("a", record.title);
link.href = record.url;
title.append(link);
card.append(element("p", record.authors.join(" / "), "muted"), title,
element("p", `${record.venue}, ${record.year} · ${record.type}`));
if (record.tags.length) {
const tags = element("div", undefined, "chip-row");
record.tags.forEach((tag) => tags.append(element("span", tag, "chip chip-muted")));
card.append(tags);
}
return card;
};
const filterURL = (page = currentPage) => {
const url = new URL(archive.dataset.publicationBase, location.href);
for (const [key, value] of [["q", searchInput.value.trim()], ["tag", activeTag], ["research", researchSelect?.value]]) {
if (value && value !== "all") url.searchParams.set(key, value);
}
if (page > 1) url.searchParams.set("page", page);
return url;
};
const renderPagination = (pageCount) => {
paginations.forEach((nav) => {
nav.replaceChildren();
const addLink = (label, page, relation) => {
const link = element("a", label, "button button-secondary");
link.href = filterURL(page);
link.rel = relation;
link.addEventListener("click", (event) => {
if (event.ctrlKey || event.metaKey || event.shiftKey || event.altKey || event.button !== 0) return;
event.preventDefault();
clearTimeout(searchTimer);
currentPage = page;
history.pushState(null, "", filterURL());
applyFilter(false).then(() => {
results.focus({ preventScroll: true });
results.scrollIntoView({ block: "start" });
});
});
nav.append(link);
};
if (currentPage > 1) addLink("Previous", currentPage - 1, "prev");
nav.append(element("span", `Page ${currentPage} of ${pageCount}`));
if (currentPage < pageCount) addLink("Next", currentPage + 1, "next");
});
};
const applyFilter = async (updateURL = true) => {
const requestRevision = ++revision;
if (!records) resultCount.textContent = "Loading publication search…";
try { await loadIndex(); } catch {
if (requestRevision === revision) {
errorState.hidden = false;
resultCount.textContent = "Browse publications using the page links below.";
}
return;
}
if (requestRevision !== revision) return;
errorState.hidden = true;
const terms = normalize(searchInput.value.trim()).split(/\s+/).filter(Boolean);
const research = researchSelect?.value || "all";
let visible = 0;
cards.forEach((card, index) => {
const tags = (card.dataset.tags || "").split("|");
const areas = (card.dataset.research || "").split("|");
const match = terms.every((term) => searchIndex[index].includes(term)) &&
(activeTag === "all" || tags.includes(activeTag)) &&
(research === "all" || areas.includes(research));
card.hidden = !match;
if (match) visible += 1;
});
const matches = records.filter((record) => terms.every((term) => record.search.includes(term)) &&
(activeTag === "all" || record.tags.includes(activeTag)) &&
(research === "all" || record.research.includes(research)));
const pageCount = Math.max(1, Math.ceil(matches.length / pageSize));
currentPage = Math.min(Math.max(1, currentPage), pageCount);
const start = (currentPage - 1) * pageSize;
results.replaceChildren(...matches.slice(start, start + pageSize).map(cardFor));
filterButtons.forEach((button) => {
const selected = button.dataset.publicationTag === activeTag;
button.classList.toggle("is-active", selected);
button.setAttribute("aria-pressed", String(selected));
});
if (emptyState) emptyState.hidden = visible !== 0;
if (resultCount) resultCount.textContent = `${visible} of ${cards.length} publications`;
if (clearButton) clearButton.disabled = !searchInput.value && activeTag === "all" && research === "all";
if (updateURL) {
const url = new URL(location.href);
url.searchParams.delete("author");
for (const [key, value] of [["q", searchInput.value.trim()], ["tag", activeTag], ["research", research]]) {
if (value && value !== "all") url.searchParams.set(key, value);
else url.searchParams.delete(key);
}
history.replaceState(null, "", url);
}
emptyState.hidden = matches.length !== 0;
resultCount.textContent = matches.length ?
`Showing ${start + 1}–${Math.min(start + pageSize, matches.length)} of ${matches.length} publications` :
"0 publications";
renderPagination(pageCount);
clearButton.disabled = !searchInput.value && activeTag === "all" && research === "all";
if (updateURL) history.replaceState(null, "", filterURL());
};
const restoreFilter = () => {
const params = new URL(location.href).searchParams;
clearTimeout(searchTimer);
++revision;
const url = new URL(location.href);
const params = url.searchParams;
searchInput.value = params.get("q") || params.get("author") || "";
const tag = params.get("tag");
activeTag = filterButtons.some((button) => button.dataset.publicationTag === tag) ? tag : "all";
if (researchSelect) {
const area = params.get("research");
researchSelect.value = [...researchSelect.options].some((option) => option.value === area) ? area : "all";
}
applyFilter(false);
const area = params.get("research");
researchSelect.value = [...researchSelect.options].some((option) => option.value === area) ? area : "all";
const page = params.get("page") || url.pathname.match(/\/page\/(\d+)\//)?.[1] || "1";
currentPage = /^[1-9]\d*$/.test(page) && Number.isSafeInteger(Number(page)) ? Number(page) : 1;
const filtered = searchInput.value || activeTag !== "all" || researchSelect.value !== "all";
if (records || filtered || params.has("page")) applyFilter(false);
clearButton.disabled = !filtered;
};
searchInput.addEventListener("input", () => applyFilter());
researchSelect?.addEventListener("change", () => applyFilter());
const changeFilter = () => {
clearTimeout(searchTimer);
currentPage = 1;
applyFilter();
};
searchInput.addEventListener("input", () => {
clearTimeout(searchTimer);
++revision;
currentPage = 1;
searchTimer = setTimeout(() => applyFilter(), 150);
});
researchSelect.addEventListener("change", changeFilter);
filterButtons.forEach((button) => button.addEventListener("click", () => {
activeTag = button.dataset.publicationTag || "all";
applyFilter();
changeFilter();
}));
clearButton?.addEventListener("click", () => {
clearButton.addEventListener("click", () => {
searchInput.value = "";
activeTag = "all";
if (researchSelect) researchSelect.value = "all";
applyFilter();
researchSelect.value = "all";
changeFilter();
searchInput.focus();
});
document.querySelector("[data-publication-retry]").addEventListener("click", () => applyFilter());
window.addEventListener("popstate", restoreFilter);
restoreFilter();
if (controls) controls.hidden = false;
controls.hidden = false;
}

const msrgGame = document.querySelector("[data-msrg-game]");
Expand Down
1 change: 1 addition & 0 deletions content/people/alex-cheung.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ start_date = "2004-09"
end_date = "2009-06"
location = "MSRG alumnus"
research = ["data-management"]
author_names = ["Alex Cheung", "Alex King Yeung Cheung"]
+++
1 change: 1 addition & 0 deletions content/people/alexander-erben.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ research = ["distributed-machine-learning"]
orcid = "https://orcid.org/0000-0002-0153-7251"
linkedin = "https://www.linkedin.com/in/alexandererben/"
end_date = "2024"
author_names = ["Alexander Erben", "Alexander Isenko"]
+++
1 change: 1 addition & 0 deletions content/people/herbert-woisetschlaeger.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ interests = ["Federated Learning", "Efficient Machine Learning"]
portrait = "/images/people/herbert-woisetschlaeger.jpg"
homepage = "https://research.ibm.com/people/herbert-woisetschlaeger"
linkedin = "https://www.linkedin.com/in/hwoisetschlaeger/"
author_names = ["Herbert Woisetschläger", "Herbert Woisetschlaeger"]
+++
1 change: 1 addition & 0 deletions content/people/jose-rivera.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ status = "alumni"
location = "MSRG alumnus"
research = ["data-management"]
homepage = "https://www.cs.cit.tum.de/dis/alumni/dr-jose-adan-rivera-acevedo/"
author_names = ["José Rivera", "Jose Rivera"]
+++
1 change: 1 addition & 0 deletions content/people/lixia-chen.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ status = "alumni"
location = "MSRG alumna"
research = ["data-management"]
orcid = "https://orcid.org/0000-0001-7943-3623"
author_names = ["Lixia Chen", "Li-Xia Chen"]
+++
1 change: 1 addition & 0 deletions content/people/michalis-bachras.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ portrait = "/images/people/michalis-bachras.jpg"
linkedin = "https://www.linkedin.com/in/michalis-bachras/"
email = "michalis.bachras@mail.utoronto.ca"
# Contact address supplied in the maintainer's group-member list, 2026-09-09.
author_names = ["Michalis Bachras", "Michail Bachras"]
+++
1 change: 1 addition & 0 deletions content/people/mohammadreza-najafi.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ location = "MSRG alumnus"
research = ["data-management"]
orcid = "https://orcid.org/0000-0002-0629-7955"
homepage = "https://www.cs.cit.tum.de/dis/alumni/dr-mohammadreza-najafi/"
author_names = ["Mohammadreza Najafi", "Mohammedreza Najafi"]
+++
1 change: 1 addition & 0 deletions content/people/victor-del-razo.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ orcid = "https://orcid.org/0000-0002-6807-9961"
linkedin = "https://www.linkedin.com/in/victordelrazo/"
start_date = "2012"
end_date = "2016"
author_names = ["Victor Del Razo", "Victor del Razo"]
+++
1 change: 1 addition & 0 deletions content/people/yuqiu-zhang.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ interests = ["Cloud Resource Management", "Serverless Computing", "Stream Proces
portrait = "/images/people/yuqiu-zhang.jpg"
homepage = "https://qzhang.ca/"
linkedin = "https://www.linkedin.com/in/yuqiu-quincy-zhang/"
author_names = ["Quincy Yuqiu Zhang", "Yuqiu Zhang"]
+++
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
+++
title = "2PS: High-Quality Edge Partitioning with Two-Phase Streaming"
year = 2020
authors = ["Ruben Mayer", "Kamil Orujzade", "Hans-Arno Jacobsen"]
venue = "arXiv"
publication_type = "ArXiv Preprint"
research = ["data-management"]
external_url = "https://arxiv.org/abs/2001.07086"
abstract = "Graph partitioning is an important preprocessing step to distributed graph processing. In edge partitioning, the edge set of a given graph is split into $k$ equally-sized partitions, such that the replication of vertices across partitions is minimized. Streaming is a viable approach to partition graphs that exceed the memory capacities of a single server. The graph is ingested as a stream of edges, and one edge at a time is immediately and irrevocably assigned to a partition based on a scoring function. However, streaming partitioning suffers from the uninformed assignment problem: At the time of partitioning early edges in the stream, there is no information available about the rest of the edges. As a consequence, edge assignments are often driven by balancing considerations, and the achieved replication factor is comparably high. In this paper, we propose 2PS, a novel two-phase streaming algorithm for high-quality edge partitioning. In the first phase, vertices are separated into clusters by a lightweight streaming clustering algorithm. In the second phase, the graph is re-streamed and edge partitioning is performed while taking into account the clustering of the vertices from the first phase. Our evaluations show that 2PS can achieve a replication factor that is comparable to heavy-weight random access partitioners while inducing orders of magnitude lower memory overhead."
+++
1 change: 1 addition & 0 deletions content/publications/_index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
+++
title = "Publications"
layout = "archive"
outputs = ["HTML", "JSON"]
summary = "Research papers, conference proceedings, and technical reports from MSRG spanning data management, distributed machine learning, and quantum computing systems."
+++
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
+++
title = "A BigBench Implementation in the Hadoop Ecosystem"
year = 2014
authors = ["Badrul Chowdhury", "Tilmann Rabl", "Pooya Saadatpanah", "Jiang Du", "Hans-Arno Jacobsen"]
venue = "Lecture Notes in Computer Science; Advancing Big Data Benchmarks"
publication_type = "Conference Paper"
research = ["data-management"]
external_url = "https://doi.org/10.1007/978-3-319-10596-3_1"
+++
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
+++
title = "A Blockchain-Based Privacy-Preserving Charging Station Reservation and Payment Scheme for Electric Vehicles"
year = 2025
authors = ["Syed Muhammad Danish", "Muhammad Muneem Shabir", "Kaiwen Zhang", "Hans-Arno Jacobsen", "Syed Ali Hassan"]
venue = "Distributed Ledger Technologies: Research and Practice"
publication_type = "Journal Article"
research = ["data-management"]
external_url = "https://doi.org/10.1145/3696428"
abstract = "EV charging infrastructures traditionally rely on untrusted centralized infrastructures that pose several privacy and security threats to EVs’ personal information. Targeted advertisements, privacy leaks and selling data to third parties are among the threats to privacy and security. By utilizing blockchain-based solutions, recent work address the security and privacy problems associated with EV charging protocols. Most of them are geared toward maintaining EV anonymity rather than preserving end-to-end privacy. As EV owners’ charging histories and payment information are associated with their wallet addresses on the blockchain, any threat of linkability of these blockchain addresses to physical identities can pose a serious risk to their privacy. In this paper, we propose a ring signature based privacy-preserving end-to-end charging station (CS) reservation and payment protocol, which provides EV owners with the ability to reserve and pay for a charging slot privately without sharing private information or exposing their identity or addresses at CS locations. Additionally, we provide EV owners with a decentralized charging slot information verification protocol with the help of secure multiparty computation (SMC), which allows them to verify available slots. A dispute resolution mechanism is also proposed that handles disputes between EVs and CSs and penalizes them accordingly by utilizing trusted execution environment (TEE). Results show that the proposed protocol ensures end-to-end EV owners’ privacy with low blockchain transaction and computation overhead."
+++
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
+++
title = "A Blockchain-Based Privacy-Preserving Intelligent Charging Station Selection for Electric Vehicles"
year = 2020
authors = ["Syed Muhammad Danish", "Kaiwen Zhang", "Hans-Arno Jacobsen"]
venue = "2020 IEEE International Conference on Blockchain and Cryptocurrency (ICBC)"
publication_type = "Conference Paper"
research = ["data-management"]
external_url = "https://doi.org/10.1109/icbc48266.2020.9169419"
abstract = "The untrusted centralized nature of energy markets and electric vehicle (EV) charging infrastructures result in several privacy and security threats to the private information of EV users. These security and privacy threats include targeted advertisements, privacy leakage, selling data to third party, etc. In this work, we propose a blockchain-based privacy-preserving intelligent charging station (CS) selection for EVs to ensure the security and privacy of the EV users and availability of the CSs. We introduce a blockchain-based framework to implement secure charging services and trusted reservation for EVs through the execution of smart contracts. We also formulate the problem of privacy-preserving intelligent CS selection and propose a mechanism for EVs to select the optimal CS locally based on dynamic requirements. Finally, we present an example scenario of our proposed framework."
+++
Loading