Newer
Older
cactus / src / main / java / com / cube / index / CubicIndexNode.java
@agalyaramadoss agalyaramadoss on 16 Feb 6 KB version update with 21
package com.cube.index;

import java.util.*;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * Cubic Index Node - Revolutionary indexing based on cube numbers.
 * 
 * Formula: Index = N³ × 6
 * Each node has 6 sides (like a cube) for data storage.
 * 
 * Index progression: 1³×6=6, 2³×6=48, 3³×6=162, 4³×6=384, 5³×6=750...
 */
public class CubicIndexNode {
    
    private final int level;           // N in N³×6
    private final long indexValue;     // N³×6
    private final CubeSide[] sides;    // 6 sides of the cube
    private final ReadWriteLock lock;
    
    // 6 sides of a cube: Front, Back, Left, Right, Top, Bottom
    public enum Side {
        FRONT(0),   // Side 0
        BACK(1),    // Side 1
        LEFT(2),    // Side 2
        RIGHT(3),   // Side 3
        TOP(4),     // Side 4
        BOTTOM(5);  // Side 5
        
        private final int index;
        
        Side(int index) {
            this.index = index;
        }
        
        public int getIndex() {
            return index;
        }
        
        public static Side fromIndex(int index) {
            for (Side side : values()) {
                if (side.index == index) {
                    return side;
                }
            }
            throw new IllegalArgumentException("Invalid side index: " + index);
        }
    }
    
    /**
     * One side of the cubic index node
     */
    public static class CubeSide {
        private final Side position;
        private final Map<String, byte[]> data;
        private final ReadWriteLock sideLock;
        
        public CubeSide(Side position) {
            this.position = position;
            this.data = new HashMap<>();
            this.sideLock = new ReentrantReadWriteLock();
        }
        
        public void put(String key, byte[] value) {
            sideLock.writeLock().lock();
            try {
                data.put(key, value);
            } finally {
                sideLock.writeLock().unlock();
            }
        }
        
        public byte[] get(String key) {
            sideLock.readLock().lock();
            try {
                return data.get(key);
            } finally {
                sideLock.readLock().unlock();
            }
        }
        
        public boolean containsKey(String key) {
            sideLock.readLock().lock();
            try {
                return data.containsKey(key);
            } finally {
                sideLock.readLock().unlock();
            }
        }
        
        public boolean remove(String key) {
            sideLock.writeLock().lock();
            try {
                return data.remove(key) != null;
            } finally {
                sideLock.writeLock().unlock();
            }
        }
        
        public int size() {
            sideLock.readLock().lock();
            try {
                return data.size();
            } finally {
                sideLock.readLock().unlock();
            }
        }
        
        public Set<String> keys() {
            sideLock.readLock().lock();
            try {
                return new HashSet<>(data.keySet());
            } finally {
                sideLock.readLock().unlock();
            }
        }
        
        public Side getPosition() {
            return position;
        }
    }
    
    /**
     * Create a cubic index node at level N
     */
    public CubicIndexNode(int level) {
        if (level < 1) {
            throw new IllegalArgumentException("Level must be >= 1");
        }
        
        this.level = level;
        this.indexValue = calculateCubicIndex(level);
        this.sides = new CubeSide[6];
        this.lock = new ReentrantReadWriteLock();
        
        // Initialize all 6 sides
        for (Side side : Side.values()) {
            sides[side.getIndex()] = new CubeSide(side);
        }
    }
    
    /**
     * Calculate cubic index: N³ × 6
     */
    public static long calculateCubicIndex(int n) {
        return (long) n * n * n * 6;
    }
    
    /**
     * Calculate which level a given value belongs to
     */
    public static int calculateLevel(long value) {
        // Solve for N in: N³ × 6 = value
        // N³ = value / 6
        // N = ∛(value / 6)
        double cubeRoot = Math.cbrt(value / 6.0);
        return (int) Math.ceil(cubeRoot);
    }
    
    /**
     * Determine which side to use based on key hash
     */
    public static Side determineSide(String key) {
        int hash = Math.abs(key.hashCode());
        return Side.fromIndex(hash % 6);
    }
    
    /**
     * Put data into the appropriate side
     */
    public void put(String key, byte[] value) {
        Side side = determineSide(key);
        sides[side.getIndex()].put(key, value);
    }
    
    /**
     * Get data from the appropriate side
     */
    public byte[] get(String key) {
        Side side = determineSide(key);
        return sides[side.getIndex()].get(key);
    }
    
    /**
     * Check if key exists on any side
     */
    public boolean containsKey(String key) {
        Side side = determineSide(key);
        return sides[side.getIndex()].containsKey(key);
    }
    
    /**
     * Remove data from the appropriate side
     */
    public boolean remove(String key) {
        Side side = determineSide(key);
        return sides[side.getIndex()].remove(key);
    }
    
    /**
     * Get a specific side
     */
    public CubeSide getSide(Side side) {
        return sides[side.getIndex()];
    }
    
    /**
     * Get total size across all sides
     */
    public int getTotalSize() {
        int total = 0;
        for (CubeSide side : sides) {
            total += side.size();
        }
        return total;
    }
    
    /**
     * Get all keys across all sides
     */
    public Set<String> getAllKeys() {
        Set<String> allKeys = new HashSet<>();
        for (CubeSide side : sides) {
            allKeys.addAll(side.keys());
        }
        return allKeys;
    }
    
    /**
     * Get statistics for this node
     */
    public Map<String, Object> getStats() {
        Map<String, Object> stats = new LinkedHashMap<>();
        stats.put("level", level);
        stats.put("indexValue", indexValue);
        stats.put("totalKeys", getTotalSize());
        
        Map<String, Integer> sideStats = new LinkedHashMap<>();
        for (Side side : Side.values()) {
            sideStats.put(side.name(), sides[side.getIndex()].size());
        }
        stats.put("sideDistribution", sideStats);
        
        return stats;
    }
    
    public int getLevel() {
        return level;
    }
    
    public long getIndexValue() {
        return indexValue;
    }
    
    @Override
    public String toString() {
        return String.format("CubicNode[L=%d, Index=%d (=%d³×6), Keys=%d]",
            level, indexValue, level, getTotalSize());
    }
}