列出缓存中的行为和使用
列表是一种无序的数据结构,可以在其中添加数据或从列表中删除数据。 例如,列表维护添加到电子商务网站购物车的产品。 假设用户将产品 Umbrella、Green Apples 和 Coffee 添加到购物车。 在进行交易之前,删除产品 Green Apples,并添加新产品 Pears。 这是可能的,因为您可以从其内部的任何点更新列表。
NCache 通过提供进一步增强列表数据结构 NCache-特定功能,例如 组别, 标签, 過期, 锁定, 依赖, 和更多。 在这种情况下,公司希望仅在会话处于活动状态时维护购物车列表。 因此,过期可以与每个创建的等于会话超时值的列表相关联。
宠物行为研究
- 列表可以是任何原始类型或自定义对象。
- 列表
CacheItem
和嵌套列表尚不支持。
- 列表可以通过索引直接访问。
- 列表被命名。 因此,您需要为列表提供唯一的缓存键。
- Null 不是受支持的值类型。
- 支持重复值。
先决条件
- 了解与所有人员合作所需的标准先决条件 NCache 客户端功能请参阅给定页面 客户端 API 先决条件.
- 有关 API 详细信息,请参阅: 缓存, 分布式列表, 数据类型管理器, 创建列表, 添加范围, 插入头, 获取列表, 删除范围, 列表, 注册通知, 数据类型数据通知回调, 事件类型, 数据类型事件数据过滤器, 锁, 开锁.
- 了解与所有人员合作所需的标准先决条件 NCache 客户端功能请参阅给定页面 客户端 API 先决条件.
- 有关 API 详细信息,请参阅: 缓存, 分布式列表, 获取数据结构管理器, 创建列表, 添加范围, 删除范围, 插入头, 获取列表, 数据结构数据更改监听器, 数据结构改变时, 添加更改监听器, 事件类型, 获取事件类型, 数据类型事件数据过滤器, 数据结构事件参数, 获取集合项, 锁, 开锁.
- 了解与所有人员合作所需的标准先决条件 NCache 客户端功能请参阅给定页面 客户端 API 先决条件.
- 有关 API 详细信息,请参阅: 缓存, 分布式列表, 获取数据结构管理器, 创建列表, 添加范围, 获取列表, 插入头, 去掉, 删除范围, 数据结构数据更改监听器, 锁, 事件类型, 添加更改监听器, 数据类型事件数据过滤器 , 数据结构事件参数, 获取事件类型, 获取集合项, 开锁, 数据结构数据更改监听器.
- 了解与所有人员合作所需的标准先决条件 NCache 客户端功能请参阅给定页面 客户端 API 先决条件.
- 有关 API 详细信息,请参阅: 缓存, 分布式列表, 数据结构管理器, 获取数据结构管理器, 创建列表, 添加_范围, 获取列表, 插入头, 获取迭代器, 移除范围, 获取事件类型, 添加更改侦听器 , 数据类型事件数据过滤器, 事件数据过滤器.
创建列表并添加数据
以下代码示例显示了如何列出 产品 可以使用以下命令在缓存中创建类型 CreateList
针对缓存键 产品列表. 产品使用添加到列表中 Add
,然后使用以下方法将新的产品范围添加到列表中 AddRange
.
Tips:
你也可以 配置可搜索属性 例如组/标签/命名标签和 失效属性 例如创建数据结构时的 Expiration/Eviction/Dependency。
// Precondition: Cache must be connected
// Specify unique cache key for list
string key = "ProductList";
// Create list of Product type
IDistributedList<Product> list = cache.DataTypeManager.CreateList<Product>(key);
// Get products to add to list
Product[] products = FetchProducts();
foreach (var product in products)
{
// Add products to list
list.Add(product);
}
// Get new products
Product[] newProducts = FetchNewProducts();
// Append list of new Products to existing list
list.AddRange(newProducts);
// Precondition: Cache must be connected
// Specify unique cache key for list
String key = "ProductList";
// Create a list of Product type
DistributedList<Product> list = cache.getDataStructuresManager().createList(key, Product.class);
// Get products to add to list
Product[] products = fetchProducts();
for (var product : products) {
// Add products to list
list.add(product);
}
// Get new products
Product[] newProducts = fetchNewProducts();
// Append list of new Products to existing list
list.addRange(Arrays.asList(newProducts));
// This is an async method
// Precondition: Cache must be connected
// Specify unique cache key for list
var key = "ProductList";
// Create list
var manager = await this.cache.getDataStructuresManager();
var list = await manager.createList(key, ncache.JsonDataType.Object);
// Get products to add to list
var products = this.fetchProducts();
for (var product in products) {
// Add products to list
list.add(product);
}
// Get new products
var newProducts = this.fetchNewProducts();
// Append list of new Products to existing list
list.addRange(newProducts);
# Precondition: Cache must be connected
# Specify unique cache key for list
key = "ProductList"
# Create list
manager = cache.get_data_structures_manager()
product_list = manager.create_list(key, Product)
# Get products to add to list
products = fetch_products()
for product in products:
# Add products to list
product_list.add(product)
# Get new products
new_products = fetch_new_products()
# Append list of new Products to existing list
product_list.add_range(new_products)
备注
为确保操作是故障安全的,建议处理应用程序中的任何潜在异常,如中所述 处理故障.
更新列表中的项目
您可以使用索引更新列表和其中的项目,因为可以通过索引访问列表。 以下代码示例使用索引更新现有列表(在上一个示例中创建)中的值。 然后它获取一个销售项目并将其添加到列表的第一个索引中使用 InsertAtHead
.
// "list" is created in previous example
// Update value of index with updated product
Product updatedProduct = GetUpdatedProductByID(11);
list[11] = updatedProduct;
// Get product on sale to insert at head of List
Product saleProduct = FetchSaleItem();
list.InsertAtHead(saleProduct);
// Precondition: Cache is already connected
// "list" is created in previous example
// Update value of index with updated product
Product updatedProduct = getUpdatedProductByID(11);
list.add(11, updatedProduct);
// Get product on sale to insert at head of List
Product saleProduct = fetchSaleItem();
list.insertAtHead(saleProduct);
// This is an async method
// Precondition: Cache is already connected
// "list" is created in previous example
// Update value of index with updated product
var updatedProduct = this.getUpdatedProductByID(11);
list.add(11, updatedProduct);
// Get product on sale to insert at head of List
var saleProduct = this.fetchSaleItem();
list.insertAtHead(fetchSaleItem);
# Precondition: Cache is already connected
# "product_list" is created in previous example
# Update value of index with updated product
updated_product = get_updated_product_by_id(1011)
product_list .add(updated_product, 1011)
# Get product on sale to insert at head of List
sale_product = fetch_sale_item()
product_list .insert_at_head(sale_product)
从缓存中获取列表
您可以使用从缓存中获取列表 GetList
它采用缓存键作为参数。 该键是在列表创建期间指定的列表的名称。
警告
如果要获取的项目不是 List 类型,则 Type mismatch
抛出异常。
// List with this key already exists in cache
string key = "ProductList";
// Get list and show items of list
IDistributedList<Product> retrievedList = cache.DataTypeManager.GetList<Product>(key);
if (retrievedList != null)
{
foreach (var item in retrievedList)
{
// Perform operations
}
}
else
{
// List does not exist
}
// Precondition: Cache is already connected
// List with this key already exists in cache
String key = "ProductList";
// Get list and show items of list
DistributedList<Product> retrievedList = cache.getDataStructuresManager().getList(key, Product.class);
if (retrievedList != null) {
for (var item : retrievedList) {
// Perform operations
}
} else {
// List does not exist
}
// This is an async method
// Precondition: Cache is already connected
// List with this key already exists in cache
var key = "ProductList";
// Get list and show items of list
var manager = await this.cache.getDataStructuresManager();
var retrievedList = await manager.getList(key, ncache.JsonDataType.Object);
if (retrievedList != null) {
for (var item in retrievedList) {
// Perform operations
}
} else {
// List does not exist
}
# Precondition: Cache is already connected
# List with this key already exists in cache
key = "ProductList"
# Get list and show items of list
manager = cache.get_data_structures_manager()
retrieved_list = manager.get_list(key, Product)
if retrieved_list is not None:
for item in retrieved_list.get_iterator():
# Perform operations
print(item)
else:
# List does not exist
print("List not found")
从列表中删除项目
可以从列表中删除单个项目或给定范围的项目。 以下代码示例使用删除单个项目 Remove
以及使用过期产品的一系列项目 RemoveRange
.
备注
如果指定要删除的键不存在,则不返回任何内容。 您可以使用返回类型验证返回的键数 RemoveRange
.
// List with this key already exists in cache
string key = "ProductList";
// Get list to remove items
IDistributedList<Product> retrievedList = cache.DataTypeManager.GetList<Product>(key);
// Get range of out of stock products to be removed
List<Product> outOfStockProducts = FetchOutOfStockProducts();
// Remove each item individually from retrievedList
foreach(Product prod in outOfStockProducts)
{
retrievedList.Remove(prod);
}
// Get range of discontinued products to be removed
List<Product> discontinuedProducts = FetchDiscontinuedProducts();
// Remove this range from retrievedList
// Number of keys removed is returned
int itemsRemoved = retrievedList.RemoveRange(discontinuedProducts);
// Precondition: Cache is already connected
// List with this key already exists in cache
String key = "ProductList";
// Get list to remove items
DistributedList<Product> retrievedList = cache.getDataStructuresManager().getList(key, Product.class);
// Get range of out of stock products to be removed
List<Product> outOfStockProducts = fetchOutOfStockProducts();
// Remove an individual item from retrieved list
for(Product prod : outOfStockProducts)
{
retrievedList.remove(prod);
}
// Get range of discontinued products to be removed
List<Product> discontinuedProducts = fetchDiscontinuedProducts();
// Remove this range from retrievedList
// Number of keys removed is returned
int itemsRemoved = retrievedList.removeRange(discontinuedProducts);
// This is an async method
// Precondition: Cache is already connected
// List with this key already exists in cache
var key = "ProductList";
// Get list to remove items
var manager = await this.cache.getDataStructuresManager();
var retrievedList = await manager.getList(key, ncache.JsonDataType.Object);
// Get range of out of stock products to be removed
var outOfStockProducts = this.fetchOutOfStockProducts();
// Remove an individual item from retrieved list
for(var prod in outOfStockProducts){
await retrievedList.remove(prod);
}
// Get range of discontinued json datatype products to be removed
var discontinuedProducts = this.fetchDiscontinuedProducts();
// Remove this range from retrievedList
// Number of keys removed is returned
var itemsRemoved = await retrievedList.removeRange(discontinuedProducts);
# Precondition: Cache is already connected
# List with this key already exists in cache
key = "ProductList"
# Get list to remove items
manager = cache.get_data_structures_manager()
retrieved_list = manager.get_list(key, Product)
# Get range of expired products to be removed
items_to_remove = fetch_expired_products()
# Remove this range from retrievedList
# Number of keys removed is returned
items_removed = retrieved_list.remove_range(collection=items_to_remove)
列表上的事件通知
您可以在列表等数据结构上注册缓存事件、基于键的事件和数据结构事件。 对于行为,请参阅 特征行为.
以下代码示例注册了一个缓存事件 ItemAdded
和 ItemUpdated
. 它还注册了一个事件 ItemAdded
和 ItemUpdated
在缓存列表中。 在缓存中创建列表后, ItemAdded
缓存级事件被触发。 但是,一旦您将项目添加到列表中, ItemAdded
数据结构事件,以及 ItemUpdated
缓存级别事件被触发。 A DataTypeEventDataFilter
指定用于量化事件执行时返回的信息量。 如此注册的事件然后为用户提供基于这些数据过滤器的信息。
在创建的列表上注册事件
// Pre-condition: Cache is connected
// Unique cache key for list
string key = "ProductList";
// Create list of Product type
IDistributedList<Product> list = cache.DataTypeManager.CreateList<Product>(key);
// Register ItemAdded, ItemUpdated, ItemRemoved events on list created
// DataTypeNotificationCallback is callback method specified
list.RegisterNotification(DataTypeDataNotificationCallback, EventType.ItemAdded |
EventType.ItemUpdated | EventType.ItemRemoved,
DataTypeEventDataFilter.Data);
// Perform operations
// Precondition: Cache is already connected
// Unique cache key for list
String key = "ProductList";
// Create list of product type
DistributedList<Product> list = cache.getDataStructuresManager().createList(key, Product.class);
// Register ItemAdded, ItemUpdated, ItemRemoved events on list created
// dataChangeListener is the specified callback method
DataStructureDataChangeListener dataChangeListener = dataStructureListener.onDataStructureChanged(collectionName, args);
EnumSet<EventType> enumSet = EnumSet.of(com.alachisoft.ncache.runtime.events.EventType.ItemAdded,
EventType.ItemUpdated, EventType.ItemRemoved);
list.addChangeListener(dataChangeListener, enumSet, DataTypeEventDataFilter.Data);
// Perform operations
// This is an async method
// Precondition: Cache is already connected
// Unique cache key for list
var key = "ProductList";
// Create list
var list = await this.cache
.getDataStructuresManager()
.createList(key, ncache.JsonDataType.Object);
// Register ItemAdded, ItemUpdated, ItemRemoved events on list created
// dataChangeListener is the specified callback method
var dataChangeListener = this.dataStructureListener.onDataStructureChanged(
collectionName,
args
);
var enumSet = enumSet.of(
ncache.EventType.ItemAdded,
ncache.EventType.ItemUpdated,
ncache.EventType.ItemRemoved
);
list.addChangeListener(
dataChangeListener,
enumSet,
ncache.DataTypeEventDataFilter.Data
);
// Perform operations
def datastructure_callback_function(collection_name, collection_event_args):
# Perform Operations
print("Event Fired for " + str(collection_name))
# Precondition: Cache is already connected
# Unique cache key for list
key = "ProductList"
# Create list
product_list = cache.get_data_structures_manager().create_list(key, Product)
# Register ItemAdded, ItemUpdated, ItemRemoved events on list created
events_list = [ncache.EventType.ITEM_ADDED, ncache.EventType.ITEM_UPDATED, ncache.EventType.ITEM_REMOVED]
product_list.add_change_listener(datastructure_callback_function, events_list, ncache.DataTypeEventDataFilter.DATA)
指定事件通知的回调
private void DataTypeDataNotificationCallback(string collectionName, DataTypeEventArg collectionEventArgs)
{
switch (collectionEventArgs.EventType)
{
case EventType.ItemAdded:
// Item has been added to the collection
break;
case EventType.ItemUpdated:
if (collectionEventArgs.CollectionItem != null)
{
// Item has been updated in the collection
// Perform operations
}
break;
case EventType.ItemRemoved:
// Item has been removed from the collection
break;
}
}
DataStructureDataChangeListener dataStructureListener = new DataStructureDataChangeListener() {
@Override
public void onDataStructureChanged(String collection, DataStructureEventArg dataStructureEventArg) {
switch (dataStructureEventArg.getEventType()) {
case ItemAdded:
// Item has been added to the collection
break;
case ItemUpdated:
if (dataStructureEventArg.getCollectionItem() != null) {
//Item has been updated in the collection
// Perform operations
}
break;
case ItemRemoved:
//Item has been removed from the collection
break;
}
}
};
dataStructureListener = new ncache.DataStructureDataChangeListener();
{
function onDataStructureChanged(collection, dataStructureEventArg) {
switch (dataStructureEventArg.getEventType()) {
case ncache.EventType.ItemAdded:
//Item has been added to the collection
break;
case ncache.EventType.ItemUpdated:
if (dataStructureEventArg.getCollectionItem() != null) {
//Item has been updated in the collection
// perform operations
}
break;
case ncache.EventType.ItemRemoved:
//Item has been removed from the collection
break;
}
}
}
def datastructure_callback_function(collection_name: str, collection_event_args: DataStructureEventArg):
if collection_event_args.get_event_type() is ncache.EventType.ITEM_ADDED:
# Item has been added to the collection
print("Item added in " + collection_name)
elif collection_event_args.get_event_type() is ncache.EventType.ITEM_UPDATED:
# Item has been updated in the collection
print("Item updated in " + collection_name)
elif collection_event_args.get_event_type() is ncache.EventType.ITEM_REMOVED:
# Item has been removed from the collection
print("Item removed from " + collection_name)
锁定列表
列表可以显式锁定和解锁以确保数据一致性。 以下代码示例创建一个列表并将其锁定 10 秒,使用 锁,然后使用 开锁.
// List exists with key "ProductList"
string key = "ProductList";
// Get list
IDistributedList<Product> list = cache.DataTypeManager.GetList<Product>(key);
// Lock list for 10 seconds
bool isLocked = list.Lock(TimeSpan.FromSeconds(10));
if (isLocked)
{
// List is successfully locked for 10 seconds
// Unless explicitly unlocked
}
else
{
// List is not locked because either:
// List is not present in the cache
// List is already locked
}
list.Unlock();
// Preconditions: Cache is already connected
// List exists with key "ProductList"
String key = "ProductList";
// Get list
DistributedList<Product> list = cache.getDataStructuresManager().getList(key, Product.class);
// Lock list for 10 seconds
boolean isLocked = list.lock(TimeSpan.FromSeconds(10));
if (isLocked) {
// List is successfully locked for 10 seconds
// Unless explicitly unlocked
} else {
// List is not locked because either:
// List is not present in the cache
// List is already locked
}
list.unlock();
更多资讯
NCache 为列表数据结构提供了一个示例应用程序 GitHub上.
参见
.NET: Alachisoft.NCache.Client.DataTypes 命名空间。
Java的: COM。alachisoft.ncache.client.数据结构 命名空间。
节点.js: 分布式列表 类。
Python: ncache.client.数据结构 类。