Nếu bạn chỉ lưu trữ một ít dữ liệu và không có nhiều thay đổi thì việc lưu trữ từng phiên bản là tốt.
Nếu bạn không cần truy cập vào phiên bản cũ của dữ liệu quá thường xuyên, tôi sẽ không lưu từng bộ nhớ cache, tôi chỉ làm cho nó để bạn có thể xây dựng lại nó.
Bạn có thể làm điều này bằng cách tiết kiệm đột biến như các giao dịch và phát lại các giao dịch (với khả năng ngăn chặn bất cứ lúc nào.
Vì vậy, bạn bắt đầu với một cấu trúc dữ liệu rỗng và bạn có thể nhận được một lệnh "Add" tiếp theo "Thay đổi" và "thêm" khác và sau đó có thể là "Xóa". Mỗi đối tượng trong số này sẽ chứa COPY (không phải là con trỏ đến cùng một đối tượng) của nội dung đang được thêm hoặc thay đổi. hoạt động vào danh sách đồng thời tắt bộ sưu tập của bạn.
Nếu bạn thấy rằng mình cần phiên bản tại dấu thời gian cũ hơn, bắt đầu bằng bộ sưu tập trống mới, phát lại cho đến khi bạn nhấn dấu thời gian đó rồi dừng lại và bạn có bộ sưu tập như lúc đó.Nếu đây là một ứng dụng rất dài và bạn thường cần truy cập các mục gần cuối, bạn có thể viết "Hoàn tác" cho từng đối tượng hoạt động thêm/thay đổi/xóa và thực sự biến đổi dữ liệu qua lại. Vì vậy, hãy tưởng tượng bạn có đối tượng dữ liệu của bạn và mảng đột biến này, bạn có thể dễ dàng chạy lên và xuống danh sách đột biến thay đổi đối tượng dữ liệu qua lại cho bất kỳ phiên bản nào bạn muốn. Bạn thậm chí có thể chứa nhiều đối tượng dữ liệu, chỉ cần tạo một đối tượng dữ liệu mới và chạy nó lên mảng đột biến (nghĩ về nó như là một dòng thời gian - nơi mỗi đột biến được lưu trữ sẽ chứa dấu thời gian hoặc số phiên bản) cho đến khi bạn nhận được với dấu thời gian bạn muốn - theo cách này bạn có thể có "mốc" mà bạn có thể truy cập ngay lập tức - ví dụ: nếu bạn chỉ định một cột mốc cho mỗi chuỗi bạn có thể làm cho phương thức addMutation được đồng bộ hóa và bộ sưu tập dữ liệu này sẽ trở thành 100% threadsafe . Lưu ý rằng nếu bạn thực sự trả về đối tượng dữ liệu, bạn chỉ nên trả về một bản sao của dữ liệu - nếu không thì lần sau bạn đột biến mốc đó, nó sẽ làm biến đổi đối tượng dữ liệu bạn trả về.
Hmm, bạn cũng có thể bao gồm chức năng "Rollup" - nếu bạn quyết định không cần truy cập vào đuôi (vài giao dịch đầu tiên), bạn có thể áp dụng chúng cho cấu trúc "Bắt đầu" và sau đó xóa chúng - từ đó bạn sao chép cấu trúc bắt đầu để bắt đầu từ đầu thay vì luôn bắt đầu với một cấu trúc dữ liệu rỗng.
Con người, đây là một mẫu tuyệt vời - bây giờ tôi muốn triển khai nó.
Nguồn
2010-06-11 17:36:20
cảm ơn: Tôi đã có lịch sử hoạt động mà tôi có thể phát lại, nhưng tất nhiên điều này yêu cầu các hoạt động O (n) truy cập trạng thái của mô hình tại một thời điểm tùy ý (cần phải phát lại tất cả các hoạt động trước điểm trong câu hỏi) –