2008-11-07 23 views
11

Tôi đang tìm cấu trúc dữ liệu hoạt động tương tự như bảng băm, nhưng vị trí bảng có giới hạn kích thước. Khi số lượng các mục trong băm đạt đến giới hạn kích thước, hàm culling nên được gọi để loại bỏ các cặp khóa/giá trị được lấy ít nhất trong bảng.Loại cấu trúc dữ liệu giống như bảng băm, nhưng các phím thường dùng được xóa là gì?

Dưới đây là một số giả về những gì tôi đang làm việc trên:

class MyClass { 
    private Map<Integer, Integer> cache = new HashMap<Integer, Integer>(); 
    public int myFunc(int n) { 
    if(cache.containsKey(n)) 
     return cache.get(n); 
    int next = . . . ; //some complicated math. guaranteed next != n. 
    int ret = 1 + myFunc(next); 
    cache.put(n, ret); 
    return ret; 
    } 
} 

gì xảy ra là có một số giá trị của nmyFunc() sẽ được gọi rất nhiều lần, nhưng nhiều giá trị khác của n mà sẽ chỉ được tính một lần. Vì vậy, bộ nhớ cache có thể lấp đầy với hàng triệu giá trị không bao giờ cần thiết nữa. Tôi muốn có một cách để bộ nhớ cache tự động xóa các phần tử không thường xuyên được truy xuất.

Điều này giống như một vấn đề phải được giải quyết, nhưng tôi không chắc cấu trúc dữ liệu mà tôi sẽ sử dụng để làm điều đó một cách hiệu quả. ai đó có thể chỉ cho tôi phương hướng đúng không?


Cập nhật Tôi biết điều này đã trở thành một vấn đề đã-được giải quyết. Nó được gọi là Cache LRU và dễ thực hiện bằng cách mở rộng lớp LinkedHashMap. Dưới đây là đoạn code mà kết hợp các giải pháp:

class MyClass { 
    private final static int SIZE_LIMIT = 1000; 
    private Map<Integer, Integer> cache = 
    new LinkedHashMap<Integer, Integer>(16, 0.75f, true) { 
     protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) 
     { 
     return size() > SIZE_LIMIT; 
     } 
    }; 
    public int myFunc(int n) { 
    if(cache.containsKey(n)) 
     return cache.get(n); 
    int next = . . . ; //some complicated math. guaranteed next != n. 
    int ret = 1 + myFunc(next); 
    cache.put(n, ret); 
    return ret; 
    } 
} 
+0

Xem thêm http://stackoverflow.com/questions/224868/easy-simple-to-use-lru-cache-in-java. –

Trả lời

17

Bạn đang tìm kiếm một LRUList/Map. Kiểm tra LinkedHashMap:

Phương pháp removeEldestEntry(Map.Entry) có thể bị ghi đè để áp dụng chính sách xóa ánh xạ cũ khi ánh xạ mới được thêm vào bản đồ.

+0

Bạn đã đánh bại tôi ... –

+0

Cảm ơn, đây chính là điều tôi muốn! – Kip

+0

Bạn được chào đón và đó là một lớp JDK, do đó không có phụ thuộc bên ngoài. – ReneS

0

Hãy xem WeakHashMap

+0

Đó không phải là chính xác những gì tôi muốn. Từ những gì tôi hiểu, một bản đồ băm yếu chỉ có nghĩa là sự hiện diện của một khóa trong bản đồ không được tính là một tham chiếu đến đối tượng, vì vậy bộ thu gom rác vẫn có thể loại bỏ nó. Vì tôi đang sử dụng số nguyên, không có cách nào để chắc chắn điều này làm những gì tôi muốn. – Kip

1

WeakHashMap có lẽ sẽ không làm những gì bạn mong đợi nó ... đọc tài liệu một cách cẩn thận và đảm bảo rằng bạn biết chính xác những gì bạn từ tài liệu tham khảo yếu và mạnh mẽ.

Tôi khuyên bạn nên xem java.util.LinkedHashMap và sử dụng phương thức removeEldestEntry để duy trì bộ nhớ cache của bạn. Nếu toán học của bạn rất chuyên sâu về tài nguyên, bạn có thể muốn di chuyển các mục nhập vào mặt trước bất cứ khi nào chúng được sử dụng để đảm bảo rằng chỉ các mục nhập không sử dụng rơi vào cuối tập hợp.

4

Googling "LRU bản đồ" và "Tôi cảm thấy may mắn" cho bạn điều này:

http://commons.apache.org/proper/commons-collections//javadocs/api-release/org/apache/commons/collections4/map/LRUMap.html

Một thực hiện Map với một cố định kích thước tối đa mà loại bỏ ít nhất entry gần đây sử dụng nếu một mục nhập là được thêm khi đầy.

Âm thanh khá nhiều chỗ trên :)

+0

Cảm ơn, đó là một trong những trường hợp thật sự dễ dàng để tìm câu trả lời nếu bạn đã biết câu trả lời là "bản đồ LRU", nhưng nếu bạn đã biết rằng bạn sẽ không cần phải tìm nó. :) – Kip

+0

Vâng, xin lỗi, đã không cố gắng để được snarky. Tôi cũng vô tình cảm nhận được "Tôi cảm thấy may mắn" :) –

1

Chính sách Adaptive Replacement Cache được thiết kế để giữ cho yêu cầu một lần từ ô nhiễm bộ nhớ cache. Điều này có thể là fancier hơn bạn đang tìm kiếm, nhưng nó trực tiếp địa chỉ của bạn "làm đầy với các giá trị mà không bao giờ cần thiết một lần nữa".

Các vấn đề liên quan