Realays Logo Realays
← Back to Blog
DevLog 11/12/2025

[Dalendar DevLog 2] Solid Foundation - Architecture and Data Structure Design

Explaining the architecture design separating View and Core Logic layers, and data structures for the EAF algorithm.

[Dalendar DevLog 2] Solid Foundation - Architecture and Data Structure Design

Episode 2: Solid Foundation - Architecture and Data Structure Design

Introduction: Why Build a Strong Foundation?

In Episode 1, we covered basic preparation for building a calendar app. In this Episode 2, we’ll dive deep into the core ‘skeleton’ of the app—the architecture and data structure design. Establishing a solid structure in software development’s early stages goes beyond good practice; it’s a critical process that determines future maintainability and scalability.

1. Project Architecture: Separation of Concerns

One common mistake is directly coupling date calculation logic with UI components like Adapters. For example, directly manipulating Android’s Calendar object in the view layer hinders code reusability and makes testing difficult. We deliberately avoid this approach by clearly separating the project’s entire structure into ‘View layer’ and ‘Core Logic layer’.

This clean boundary was an essential design decision for integrating a pure, high-performance mathematical engine (EAF) that is completely independent of the Android framework. This Separation of Concerns principle maximizes maintainability and scalability by reducing code complexity and allowing each layer to evolve independently.

1.1. View Layer: Efficient Calendar UI Structure

The View layer handles the user interface (UI) that users directly interact with. In our current project structure, MainActivity.kt serves as the container for the entire screen. The actual calendar display is handled by adapterMonth.kt and adapterDay.kt, using nested RecyclerView structure for efficiency.

Outer RecyclerView (A): This RecyclerView holds month-unit items, allowing users to scroll left and right to explore previous and next months.

Inner RecyclerView (B): Inside each month item of the outer RecyclerView exists another RecyclerView. This displays the days of each month in a 6-row by 7-column grid format.

This nested RecyclerView structure is highly effective for optimizing memory usage by recycling views not visible on screen and efficiently implementing infinite scrolling.

1.2. Core Logic Layer: Optimized Date Calculation Engine

All date-related calculations are handled through highly optimized mathematical algorithms presented in the “Euclidean Affine Functions and Applications to Calendar Algorithms” paper. This layer is like the brain of the calendar, operating completely independently of the user interface.

Deliberately avoiding simple library calls and adopting EAF is an intentional performance optimization strategy. While look-up table approaches used by general-purpose libraries exhibit unpredictable memory access patterns causing L1 cache misses, EAF efficiently fills the CPU pipeline with pure arithmetic operations.

Additionally, Euclidean Affine Function (EAF) based algorithms minimize branching, reducing the possibility of processor execution pipeline stalls and delivering fast, accurate results.

1.3. Benefits of This Structure

The clear separation of View and Core Logic layers provides these practical advantages:

Maintainability: When changing UI design, core date calculation logic remains unaffected. Similarly, when improving date calculation algorithm performance or fixing bugs, no UI code modification is needed.

Scalability: For future features like lunar conversion or specific country holiday calculations, developers can focus solely on the Core Logic layer, adding new modules or extending existing logic. The UI layer simply needs to receive and display changed data, making feature additions systematic and efficient.

2. Core Data Structures and Flow

While the database schema for permanently storing user schedules is still in the pre-design stage, defining how data is represented and processed within the app is crucial for calendar’s basic operation.

2.1. Data Representation: Date (YMD) and Rata Die

We adopted the ‘Rata Die’ concept presented in the “Euclidean affine functions” paper as the app’s core data representation method. Rata Die expresses the number of days elapsed from a specific epoch as a single integer.

This approach elegantly circumvents the complexity of variable month lengths and leap years. For example, calculating the date 35 days from a specific date is simply integer addition: rata_die + 35. This is far more efficient and computationally cheaper than traditional methods requiring complex boundary checks for month transitions or year-end processing.

Inside the app, all date-related logic is processed based on this Rata Die value, converting to familiar Year/Month/Day (YMD) format only when displaying to users.

Moreover, Rata Die contributes to UI performance. Using simple integers for all internal calculations means the logic passed to the UI layer is incredibly light. adapterMonth doesn’t need to manipulate complex Date or Calendar objects—it only calculates the starting Rata Die value for that month, and the rest is handled by simple integer loops. This reduces object creation overhead in adapters, complementing RecyclerView’s view recycling mechanism.

###2.2. Data Flow: How the Calendar is Rendered

When users launch the app and scroll through months, data flows through these stages to finally render on screen:

  1. Initialization: When users launch the app, MainActivity.kt sets the initial display position of the month-unit RecyclerView (A) to Int.MAX_VALUE / 2, placing the current month at the center of the scrollable range.

  2. Month Creation: adapterMonth.kt calculates the year and month to display using the position value passed from RecyclerView, determining the relative month via position - center calculation.

  3. Day List Generation: Based on the 1st day of the calculated month, it generates a dayList (6×7 grid, 42 total cells) to fill the calendar grid.

  4. Data Transfer: The generated dayList containing 42 dates is passed to the inner RecyclerView (B) and its adapter adapterDay.kt.

  5. UI Rendering: adapterDay.kt displays each date from the received dayList sequentially in grid cells, completing the final calendar UI.

3. Why These Technologies?

3.1. RecyclerView: Core of Android UI Performance

RecyclerView is essential for ensuring performance when implementing list-style UIs in Android. Its core principle is the ‘view recycling’ mechanism—creating only the minimum ViewHolder frames needed for on-screen display, then reusing ViewHolders that scroll off-screen with new data.

This minimizes unnecessary view object creation, using system resources extremely efficiently. The result is improved overall app performance and responsiveness, enhancing user experience quality and facilitating maintenance even in complex UIs.

3.2. EAF Algorithm: Unmatched Calculation Speed and Scalability

The reason for choosing EAF (Euclidean Affine Functions) based algorithms for date calculation is clear: overwhelming performance and resulting scalability. According to the paper’s performance analysis section, this algorithm shows more than 2x faster performance than date calculation functions in widely-used standard libraries like glibc, OpenJDK, and Boost.

This performance guarantees fast, accurate calculations without delay even when the app handles vast date ranges spanning hundreds or thousands of years. This is the core of the ‘scalability’ this app pursues.

EAF optimizes simple division operations into multiplication and bit shift operations, going beyond compiler-level optimization. The true power of this optimization lies in breaking data dependencies, enabling instruction-level parallelism on modern CPUs.

As shown in Example 3.12 of the paper, traditional approaches require the quotient (n2 / 1461) to complete before calculating the remainder (n2 % 1461). EAF optimization transforms this. First, it calculates the 64-bit intermediate value u2 = 2939745 * n2. From this single value, quotient q2 can be extracted from upper 32 bits (u2 / 2^32) and remainder r2 from lower 32 bits (u2 % 2^32) concurrently. The CPU doesn’t need to wait for quotient calculation to start remainder calculation. This parallel execution path, even saving just a few clock cycles per operation, has tremendous performance impact when quickly scrolling through decades of calendar data.

Conclusion: Solid Foundation for Next Steps

In this Episode 2, we designed three core elements forming the app’s solid skeleton. The View/Logic separation architecture provides the ‘chassis’ for mounting the powerful EAF engine, Rata Die supplies high-efficiency ‘fuel’ to this engine, and the EAF algorithm serves as the app’s heart—the ‘engine’ itself.

With these three elements perfectly interlocked, we can confidently expand rich features without worrying about performance degradation. On this firmly established foundation, the next episode will cover user scheduling features and database integration for permanent storage.

Next Episode Preview:

  • User schedule management implementation
  • Database schema design and integration
  • Event persistence and retrieval optimization
  • Testing strategies for data layer

Stay tuned as we add flesh to these strong bones!

Related Posts